The Man in the High Castle Wiki
themaninthehighcastlewiki
https://themaninthehighcastle.miraheze.org/wiki/Main_Page
MediaWiki 1.40.2
first-letter
Media
Special
Talk
User
User talk
The Man in the High Castle Wiki
The Man in the High Castle Wiki talk
File
File talk
MediaWiki
MediaWiki talk
Template
Template talk
Help
Help talk
Category
Category talk
Module
Module talk
Main Page
0
1
1
2023-12-27T03:56:57Z
MediaWiki default
1
Create main page
wikitext
text/x-wiki
__NOTOC__
== Welcome to {{SITENAME}}! ==
This Main Page was created automatically and it seems it hasn't been replaced yet.
=== For the bureaucrat(s) of this wiki ===
Hello, and welcome to your new wiki! Thank you for choosing Miraheze for the hosting of your wiki, we hope you will enjoy our hosting.
You can immediately start working on your wiki or whenever you want.
Need help? No problem! We will help you with your wiki as needed. To start, try checking out these helpful links:
* [[mw:Special:MyLanguage/Help:Contents|MediaWiki guide]] (e.g. navigation, editing, deleting pages, blocking users)
* [[meta:Special:MyLanguage/FAQ|Miraheze FAQ]]
* [[meta:Special:MyLanguage/Request features|Request settings changes on your wiki]]. (Extensions, Skin and Logo/Favicon changes should be done through [[Special:ManageWiki]] on your wiki, see [[meta:Special:MyLanguage/ManageWiki|ManageWiki]] for more information.)
==== I still don't understand X! ====
Well, that's no problem. Even if something isn't explained in the documentation/FAQ, we are still happy to help you. You can find us here:
* [[meta:Special:MyLanguage/Help center|On our own Miraheze wiki]]
* On [[phab:|Phabricator]]
* On [https://miraheze.org/discord Discord]
* On IRC in #miraheze on irc.libera.chat ([irc://irc.libera.chat/%23miraheze direct link]; [https://web.libera.chat/?channel=#miraheze webchat])
=== For visitors of this wiki ===
Hello, the default Main Page of this wiki (this page) has not yet been replaced by the bureaucrat(s) of this wiki. The bureaucrat(s) might still be working on a Main Page, so please check again later!
21236ac3f8d65e5563b6da6b70815ca6bf1e6616
2
1
2023-12-27T04:09:08Z
CreepersNeedHugs
2
Replaced the auto-generated main page.
wikitext
text/x-wiki
__NOTOC__
==Welcome to ''The Man in the High Castle'' Wiki==
Welcome to The Man in the High Castle Wiki! This wiki intends to document the characters and events of the [[The Man in the High Castle (novel)|novel]] and [[The Man in the High Castle (television series)|television series]] ''The Man in the High Castle''.
This main page, along with the rest of the wiki, is still a work in progress. You, the reader, can help us by creating and editing pages on this wiki.
8b9a5026459e592ff79ff02d499e1d5c1828e4f3
Module:Infobox
828
2
3
2023-12-27T04:38:24Z
CreepersNeedHugs
2
Created Module:Infobox.
Scribunto
text/plain
--
-- This module implements {{Infobox}}
--
local p = {}
local args = {}
local origArgs = {}
local root
local function notempty( s ) return s and s:match( '%S' ) end
local function fixChildBoxes(sval, tt)
if notempty(sval) then
local marker = '<span class=special_infobox_marker>'
local s = sval
s = mw.ustring.gsub(s, '(<%s*[Tt][Rr])', marker .. '%1')
s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>)', '%1' .. marker)
if s:match(marker) then
s = mw.ustring.gsub(s, marker .. '%s*' .. marker, '')
s = mw.ustring.gsub(s, '([\r\n]|-[^\r\n]*[\r\n])%s*' .. marker, '%1')
s = mw.ustring.gsub(s, marker .. '%s*([\r\n]|-)', '%1')
s = mw.ustring.gsub(s, '(</[Cc][Aa][Pp][Tt][Ii][Oo][Nn]%s*>%s*)' .. marker, '%1')
s = mw.ustring.gsub(s, '(<%s*[Tt][Aa][Bb][Ll][Ee][^<>]*>%s*)' .. marker, '%1')
s = mw.ustring.gsub(s, '^(%{|[^\r\n]*[\r\n]%s*)' .. marker, '%1')
s = mw.ustring.gsub(s, '([\r\n]%{|[^\r\n]*[\r\n]%s*)' .. marker, '%1')
s = mw.ustring.gsub(s, marker .. '(%s*</[Tt][Aa][Bb][Ll][Ee]%s*>)', '%1')
s = mw.ustring.gsub(s, marker .. '(%s*\n|%})', '%1')
end
if s:match(marker) then
local subcells = mw.text.split(s, marker)
s = ''
for k = 1, #subcells do
if k == 1 then
s = s .. subcells[k] .. '</' .. tt .. '></tr>'
elseif k == #subcells then
local rowstyle = ' style="display:none"'
if notempty(subcells[k]) then rowstyle = '' end
s = s .. '<tr' .. rowstyle ..'><' .. tt .. ' colspan=2>\n' .. subcells[k]
elseif notempty(subcells[k]) then
if (k % 2) == 0 then
s = s .. subcells[k]
else
s = s .. '<tr><' .. tt .. ' colspan=2>\n' .. subcells[k] .. '</' .. tt .. '></tr>'
end
end
end
end
-- the next two lines add a newline at the end of lists for the PHP parser
-- https://en.wikipedia.org/w/index.php?title=Template_talk:Infobox_musical_artist&oldid=849054481
-- remove when [[:phab:T191516]] is fixed or OBE
s = mw.ustring.gsub(s, '([\r\n][%*#;:][^\r\n]*)$', '%1\n')
s = mw.ustring.gsub(s, '^([%*#;:][^\r\n]*)$', '%1\n')
s = mw.ustring.gsub(s, '^([%*#;:])', '\n%1')
s = mw.ustring.gsub(s, '^(%{%|)', '\n%1')
return s
else
return sval
end
end
local function union(t1, t2)
-- Returns the union of the values of two tables, as a sequence.
local vals = {}
for k, v in pairs(t1) do
vals[v] = true
end
for k, v in pairs(t2) do
vals[v] = true
end
local ret = {}
for k, v in pairs(vals) do
table.insert(ret, k)
end
return ret
end
local function getArgNums(prefix)
-- Returns a table containing the numbers of the arguments that exist
-- for the specified prefix. For example, if the prefix was 'data', and
-- 'data1', 'data2', and 'data5' exist, it would return {1, 2, 5}.
local nums = {}
for k, v in pairs(args) do
local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)$')
if num then table.insert(nums, tonumber(num)) end
end
table.sort(nums)
return nums
end
local function addRow(rowArgs)
-- Adds a row to the infobox, with either a header cell
-- or a label/data cell combination.
if rowArgs.header and rowArgs.header ~= '_BLANK_' then
root
:tag('tr')
:addClass(rowArgs.rowclass)
:cssText(rowArgs.rowstyle)
:attr('id', rowArgs.rowid)
:tag('th')
:attr('colspan', 2)
:attr('id', rowArgs.headerid)
:addClass(rowArgs.class)
:addClass(args.headerclass)
:css('text-align', 'center')
:cssText(args.headerstyle)
:cssText(rowArgs.rowcellstyle)
:wikitext(fixChildBoxes(rowArgs.header, 'th'))
elseif rowArgs.data then
if not rowArgs.data:gsub('%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*]]', ''):match('^%S') then
rowArgs.rowstyle = 'display:none'
end
local row = root:tag('tr')
row:addClass(rowArgs.rowclass)
row:cssText(rowArgs.rowstyle)
row:attr('id', rowArgs.rowid)
if rowArgs.label then
row
:tag('th')
:attr('scope', 'row')
:attr('id', rowArgs.labelid)
:cssText(args.labelstyle)
:cssText(rowArgs.rowcellstyle)
:wikitext(rowArgs.label)
:done()
end
local dataCell = row:tag('td')
if not rowArgs.label then
dataCell
:attr('colspan', 2)
:css('text-align', 'center')
end
dataCell
:attr('id', rowArgs.dataid)
:addClass(rowArgs.class)
:cssText(rowArgs.datastyle)
:cssText(rowArgs.rowcellstyle)
:wikitext(fixChildBoxes(rowArgs.data, 'td'))
end
end
local function renderTitle()
if not args.title then return end
root
:tag('caption')
:addClass(args.titleclass)
:cssText(args.titlestyle)
:wikitext(args.title)
end
local function renderAboveRow()
if not args.above then return end
root
:tag('tr')
:tag('th')
:attr('colspan', 2)
:addClass(args.aboveclass)
:css('text-align', 'center')
:css('font-size', '125%')
:css('font-weight', 'bold')
:cssText(args.abovestyle)
:wikitext(fixChildBoxes(args.above,'th'))
end
local function renderBelowRow()
if not args.below then return end
root
:tag('tr')
:tag('td')
:attr('colspan', '2')
:addClass(args.belowclass)
:css('text-align', 'center')
:cssText(args.belowstyle)
:wikitext(fixChildBoxes(args.below,'td'))
end
local function renderSubheaders()
if args.subheader then
args.subheader1 = args.subheader
end
if args.subheaderrowclass then
args.subheaderrowclass1 = args.subheaderrowclass
end
local subheadernums = getArgNums('subheader')
for k, num in ipairs(subheadernums) do
addRow({
data = args['subheader' .. tostring(num)],
datastyle = args.subheaderstyle,
rowcellstyle = args['subheaderstyle' .. tostring(num)],
class = args.subheaderclass,
rowclass = args['subheaderrowclass' .. tostring(num)]
})
end
end
local function renderImages()
if args.image then
args.image1 = args.image
end
if args.caption then
args.caption1 = args.caption
end
local imagenums = getArgNums('image')
for k, num in ipairs(imagenums) do
local caption = args['caption' .. tostring(num)]
local data = mw.html.create():wikitext(args['image' .. tostring(num)])
if caption then
data
:tag('div')
:cssText(args.captionstyle)
:wikitext(caption)
end
addRow({
data = tostring(data),
datastyle = args.imagestyle,
class = args.imageclass,
rowclass = args['imagerowclass' .. tostring(num)]
})
end
end
local function preprocessRows()
-- Gets the union of the header and data argument numbers,
-- and renders them all in order using addRow.
local rownums = union(getArgNums('header'), getArgNums('data'))
table.sort(rownums)
local lastheader
for k, num in ipairs(rownums) do
if args['header' .. tostring(num)] then
if lastheader then
args['header' .. tostring(lastheader)] = nil
end
lastheader = num
elseif args['data' .. tostring(num)] and args['data' .. tostring(num)]:gsub('%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*]]', ''):match('^%S') then
local data = args['data' .. tostring(num)]
if data:gsub('%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*]]', ''):match('%S') then
lastheader = nil
end
end
end
if lastheader then
args['header' .. tostring(lastheader)] = nil
end
end
local function renderRows()
-- Gets the union of the header and data argument numbers,
-- and renders them all in order using addRow.
local rownums = union(getArgNums('header'), getArgNums('data'))
table.sort(rownums)
for k, num in ipairs(rownums) do
addRow({
header = args['header' .. tostring(num)],
label = args['label' .. tostring(num)],
data = args['data' .. tostring(num)],
datastyle = args.datastyle,
class = args['class' .. tostring(num)],
rowclass = args['rowclass' .. tostring(num)],
rowstyle = args['rowstyle' .. tostring(num)],
rowcellstyle = args['rowcellstyle' .. tostring(num)],
dataid = args['dataid' .. tostring(num)],
labelid = args['labelid' .. tostring(num)],
headerid = args['headerid' .. tostring(num)],
rowid = args['rowid' .. tostring(num)]
})
end
end
local function renderItalicTitle()
local italicTitle = args['italic title'] and mw.ustring.lower(args['italic title'])
if italicTitle == '' or italicTitle == 'force' or italicTitle == 'yes' then
root:wikitext(mw.getCurrentFrame():expandTemplate({title = 'italic title'}))
end
end
local function _infobox()
-- Specify the overall layout of the infobox, with special settings
-- if the infobox is used as a 'child' inside another infobox.
if args.child ~= 'yes' then
root = mw.html.create('table')
root
:addClass((args.subbox ~= 'yes') and 'infobox' or nil)
:addClass(args.bodyclass)
if args.subbox == 'yes' then
root
:css('padding', '0')
:css('border', 'none')
:css('margin', '-3px')
:css('width', 'auto')
:css('min-width', '100%')
:css('font-size', '100%')
:css('clear', 'none')
:css('float', 'none')
:css('background-color', 'transparent')
else
root
:css('width', '22em')
end
root
:cssText(args.bodystyle)
renderTitle()
renderAboveRow()
else
root = mw.html.create()
root
:wikitext(args.title)
end
renderSubheaders()
renderImages()
if args.autoheaders then
preprocessRows()
end
renderRows()
renderBelowRow()
renderItalicTitle()
return tostring(root)
end
local function preprocessSingleArg(argName)
-- If the argument exists and isn't blank, add it to the argument table.
-- Blank arguments are treated as nil to match the behaviour of ParserFunctions.
if origArgs[argName] and origArgs[argName] ~= '' then
args[argName] = origArgs[argName]
end
end
local function preprocessArgs(prefixTable, step)
-- Assign the parameters with the given prefixes to the args table, in order, in batches
-- of the step size specified. This is to prevent references etc. from appearing in the
-- wrong order. The prefixTable should be an array containing tables, each of which has
-- two possible fields, a "prefix" string and a "depend" table. The function always parses
-- parameters containing the "prefix" string, but only parses parameters in the "depend"
-- table if the prefix parameter is present and non-blank.
if type(prefixTable) ~= 'table' then
error("Non-table value detected for the prefix table", 2)
end
if type(step) ~= 'number' then
error("Invalid step value detected", 2)
end
-- Get arguments without a number suffix, and check for bad input.
for i,v in ipairs(prefixTable) do
if type(v) ~= 'table' or type(v.prefix) ~= "string" or (v.depend and type(v.depend) ~= 'table') then
error('Invalid input detected to preprocessArgs prefix table', 2)
end
preprocessSingleArg(v.prefix)
-- Only parse the depend parameter if the prefix parameter is present and not blank.
if args[v.prefix] and v.depend then
for j, dependValue in ipairs(v.depend) do
if type(dependValue) ~= 'string' then
error('Invalid "depend" parameter value detected in preprocessArgs')
end
preprocessSingleArg(dependValue)
end
end
end
-- Get arguments with number suffixes.
local a = 1 -- Counter variable.
local moreArgumentsExist = true
while moreArgumentsExist == true do
moreArgumentsExist = false
for i = a, a + step - 1 do
for j,v in ipairs(prefixTable) do
local prefixArgName = v.prefix .. tostring(i)
if origArgs[prefixArgName] then
moreArgumentsExist = true -- Do another loop if any arguments are found, even blank ones.
preprocessSingleArg(prefixArgName)
end
-- Process the depend table if the prefix argument is present and not blank, or
-- we are processing "prefix1" and "prefix" is present and not blank, and
-- if the depend table is present.
if v.depend and (args[prefixArgName] or (i == 1 and args[v.prefix])) then
for j,dependValue in ipairs(v.depend) do
local dependArgName = dependValue .. tostring(i)
preprocessSingleArg(dependArgName)
end
end
end
end
a = a + step
end
end
local function parseDataParameters()
-- Parse the data parameters in the same order that the old {{infobox}} did, so that
-- references etc. will display in the expected places. Parameters that depend on
-- another parameter are only processed if that parameter is present, to avoid
-- phantom references appearing in article reference lists.
preprocessSingleArg('autoheaders')
preprocessSingleArg('child')
preprocessSingleArg('bodyclass')
preprocessSingleArg('subbox')
preprocessSingleArg('bodystyle')
preprocessSingleArg('title')
preprocessSingleArg('titleclass')
preprocessSingleArg('titlestyle')
preprocessSingleArg('above')
preprocessSingleArg('aboveclass')
preprocessSingleArg('abovestyle')
preprocessArgs({
{prefix = 'subheader', depend = {'subheaderstyle', 'subheaderrowclass'}}
}, 10)
preprocessSingleArg('subheaderstyle')
preprocessSingleArg('subheaderclass')
preprocessArgs({
{prefix = 'image', depend = {'caption', 'imagerowclass'}}
}, 10)
preprocessSingleArg('captionstyle')
preprocessSingleArg('imagestyle')
preprocessSingleArg('imageclass')
preprocessArgs({
{prefix = 'header'},
{prefix = 'data', depend = {'label'}},
{prefix = 'rowclass'},
{prefix = 'rowstyle'},
{prefix = 'rowcellstyle'},
{prefix = 'class'},
{prefix = 'dataid'},
{prefix = 'labelid'},
{prefix = 'headerid'},
{prefix = 'rowid'}
}, 50)
preprocessSingleArg('headerclass')
preprocessSingleArg('headerstyle')
preprocessSingleArg('labelstyle')
preprocessSingleArg('datastyle')
preprocessSingleArg('below')
preprocessSingleArg('belowclass')
preprocessSingleArg('belowstyle')
preprocessSingleArg('name')
args['italic title'] = origArgs['italic title'] -- different behaviour if blank or absent
preprocessSingleArg('decat')
end
function p.infobox(frame)
-- If called via #invoke, use the args passed into the invoking template.
-- Otherwise, for testing purposes, assume args are being passed directly in.
if frame == mw.getCurrentFrame() then
origArgs = frame:getParent().args
else
origArgs = frame
end
parseDataParameters()
return _infobox()
end
function p.infoboxTemplate(frame)
-- For calling via #invoke within a template
origArgs = {}
for k,v in pairs(frame.args) do origArgs[k] = mw.text.trim(v) end
parseDataParameters()
return _infobox()
end
return p
c6ac51f9e2faf9c2f3aba1fb8c05af98db47f4d4
Template:Infobox
10
3
4
2023-12-27T04:40:38Z
CreepersNeedHugs
2
Created page with "{{#invoke:Infobox|infobox}}<noinclude> {{documentation}} </noinclude>"
wikitext
text/x-wiki
{{#invoke:Infobox|infobox}}<noinclude>
{{documentation}}
</noinclude>
627ee6fcf4d4f108fe054b5c476201cad0ed7717
Template:Documentation
10
4
5
2023-12-27T04:42:18Z
CreepersNeedHugs
2
Created page with "-- This module implements {{documentation}}. -- Get required modules. local getArgs = require('Module:Arguments').getArgs -- Get the config table. local cfg = mw.loadData('Module:Documentation/config') local p = {} -- Often-used functions. local ugsub = mw.ustring.gsub ---------------------------------------------------------------------------- -- Helper functions -- -- These are defined as local functions, but are made available in the p -- table for testing purpos..."
wikitext
text/x-wiki
-- This module implements {{documentation}}.
-- Get required modules.
local getArgs = require('Module:Arguments').getArgs
-- Get the config table.
local cfg = mw.loadData('Module:Documentation/config')
local p = {}
-- Often-used functions.
local ugsub = mw.ustring.gsub
----------------------------------------------------------------------------
-- Helper functions
--
-- These are defined as local functions, but are made available in the p
-- table for testing purposes.
----------------------------------------------------------------------------
local function message(cfgKey, valArray, expectType)
--[[
-- Gets a message from the cfg table and formats it if appropriate.
-- The function raises an error if the value from the cfg table is not
-- of the type expectType. The default type for expectType is 'string'.
-- If the table valArray is present, strings such as $1, $2 etc. in the
-- message are substituted with values from the table keys [1], [2] etc.
-- For example, if the message "foo-message" had the value 'Foo $2 bar $1.',
-- message('foo-message', {'baz', 'qux'}) would return "Foo qux bar baz."
--]]
local msg = cfg[cfgKey]
expectType = expectType or 'string'
if type(msg) ~= expectType then
error('message: type error in message cfg.' .. cfgKey .. ' (' .. expectType .. ' expected, got ' .. type(msg) .. ')', 2)
end
if not valArray then
return msg
end
local function getMessageVal(match)
match = tonumber(match)
return valArray[match] or error('message: no value found for key $' .. match .. ' in message cfg.' .. cfgKey, 4)
end
return ugsub(msg, '$([1-9][0-9]*)', getMessageVal)
end
p.message = message
local function makeWikilink(page, display)
if display then
return mw.ustring.format('[[%s|%s]]', page, display)
else
return mw.ustring.format('[[%s]]', page)
end
end
p.makeWikilink = makeWikilink
local function makeCategoryLink(cat, sort)
local catns = mw.site.namespaces[14].name
return makeWikilink(catns .. ':' .. cat, sort)
end
p.makeCategoryLink = makeCategoryLink
local function makeUrlLink(url, display)
return mw.ustring.format('[%s %s]', url, display)
end
p.makeUrlLink = makeUrlLink
local function makeToolbar(...)
local ret = {}
local lim = select('#', ...)
if lim < 1 then
return nil
end
for i = 1, lim do
ret[#ret + 1] = select(i, ...)
end
-- 'documentation-toolbar'
return '<span class="' .. message('toolbar-class') .. '">('
.. table.concat(ret, ' | ') .. ')</span>'
end
p.makeToolbar = makeToolbar
----------------------------------------------------------------------------
-- Argument processing
----------------------------------------------------------------------------
local function makeInvokeFunc(funcName)
return function (frame)
local args = getArgs(frame, {
valueFunc = function (key, value)
if type(value) == 'string' then
value = value:match('^%s*(.-)%s*$') -- Remove whitespace.
if key == 'heading' or value ~= '' then
return value
else
return nil
end
else
return value
end
end
})
return p[funcName](args)
end
end
----------------------------------------------------------------------------
-- Entry points
----------------------------------------------------------------------------
function p.nonexistent(frame)
if mw.title.getCurrentTitle().subpageText == 'testcases' then
return frame:expandTemplate{title = 'module test cases notice'}
else
return p.main(frame)
end
end
p.main = makeInvokeFunc('_main')
function p._main(args)
--[[
-- This function defines logic flow for the module.
-- @args - table of arguments passed by the user
--]]
local env = p.getEnvironment(args)
local root = mw.html.create()
root
:tag('div')
-- 'documentation-container'
:addClass(message('container'))
:attr('role', 'complementary')
:attr('aria-labelledby', args.heading ~= '' and 'documentation-heading' or nil)
:attr('aria-label', args.heading == '' and 'Documentation' or nil)
:newline()
:tag('div')
-- 'documentation'
:addClass(message('main-div-classes'))
:newline()
:wikitext(p._startBox(args, env))
:wikitext(p._content(args, env))
:tag('div')
-- 'documentation-clear'
:addClass(message('clear'))
:done()
:newline()
:done()
:wikitext(p._endBox(args, env))
:done()
:wikitext(p.addTrackingCategories(env))
-- 'Module:Documentation/styles.css'
return mw.getCurrentFrame():extensionTag (
'templatestyles', '', {src=cfg['templatestyles']
}) .. tostring(root)
end
----------------------------------------------------------------------------
-- Environment settings
----------------------------------------------------------------------------
function p.getEnvironment(args)
--[[
-- Returns a table with information about the environment, including title
-- objects and other namespace- or path-related data.
-- @args - table of arguments passed by the user
--
-- Title objects include:
-- env.title - the page we are making documentation for (usually the current title)
-- env.templateTitle - the template (or module, file, etc.)
-- env.docTitle - the /doc subpage.
-- env.sandboxTitle - the /sandbox subpage.
-- env.testcasesTitle - the /testcases subpage.
--
-- Data includes:
-- env.subjectSpace - the number of the title's subject namespace.
-- env.docSpace - the number of the namespace the title puts its documentation in.
-- env.docpageBase - the text of the base page of the /doc, /sandbox and /testcases pages, with namespace.
-- env.compareUrl - URL of the Special:ComparePages page comparing the sandbox with the template.
--
-- All table lookups are passed through pcall so that errors are caught. If an error occurs, the value
-- returned will be nil.
--]]
local env, envFuncs = {}, {}
-- Set up the metatable. If triggered we call the corresponding function in the envFuncs table. The value
-- returned by that function is memoized in the env table so that we don't call any of the functions
-- more than once. (Nils won't be memoized.)
setmetatable(env, {
__index = function (t, key)
local envFunc = envFuncs[key]
if envFunc then
local success, val = pcall(envFunc)
if success then
env[key] = val -- Memoise the value.
return val
end
end
return nil
end
})
function envFuncs.title()
-- The title object for the current page, or a test page passed with args.page.
local title
local titleArg = args.page
if titleArg then
title = mw.title.new(titleArg)
else
title = mw.title.getCurrentTitle()
end
return title
end
function envFuncs.templateTitle()
--[[
-- The template (or module, etc.) title object.
-- Messages:
-- 'sandbox-subpage' --> 'sandbox'
-- 'testcases-subpage' --> 'testcases'
--]]
local subjectSpace = env.subjectSpace
local title = env.title
local subpage = title.subpageText
if subpage == message('sandbox-subpage') or subpage == message('testcases-subpage') then
return mw.title.makeTitle(subjectSpace, title.baseText)
else
return mw.title.makeTitle(subjectSpace, title.text)
end
end
function envFuncs.docTitle()
--[[
-- Title object of the /doc subpage.
-- Messages:
-- 'doc-subpage' --> 'doc'
--]]
local title = env.title
local docname = args[1] -- User-specified doc page.
local docpage
if docname then
docpage = docname
else
docpage = env.docpageBase .. '/' .. message('doc-subpage')
end
return mw.title.new(docpage)
end
function envFuncs.sandboxTitle()
--[[
-- Title object for the /sandbox subpage.
-- Messages:
-- 'sandbox-subpage' --> 'sandbox'
--]]
return mw.title.new(env.docpageBase .. '/' .. message('sandbox-subpage'))
end
function envFuncs.testcasesTitle()
--[[
-- Title object for the /testcases subpage.
-- Messages:
-- 'testcases-subpage' --> 'testcases'
--]]
return mw.title.new(env.docpageBase .. '/' .. message('testcases-subpage'))
end
function envFuncs.subjectSpace()
-- The subject namespace number.
return mw.site.namespaces[env.title.namespace].subject.id
end
function envFuncs.docSpace()
-- The documentation namespace number. For most namespaces this is the
-- same as the subject namespace. However, pages in the Article, File,
-- MediaWiki or Category namespaces must have their /doc, /sandbox and
-- /testcases pages in talk space.
local subjectSpace = env.subjectSpace
if subjectSpace == 0 or subjectSpace == 6 or subjectSpace == 8 or subjectSpace == 14 then
return subjectSpace + 1
else
return subjectSpace
end
end
function envFuncs.docpageBase()
-- The base page of the /doc, /sandbox, and /testcases subpages.
-- For some namespaces this is the talk page, rather than the template page.
local templateTitle = env.templateTitle
local docSpace = env.docSpace
local docSpaceText = mw.site.namespaces[docSpace].name
-- Assemble the link. docSpace is never the main namespace, so we can hardcode the colon.
return docSpaceText .. ':' .. templateTitle.text
end
function envFuncs.compareUrl()
-- Diff link between the sandbox and the main template using [[Special:ComparePages]].
local templateTitle = env.templateTitle
local sandboxTitle = env.sandboxTitle
if templateTitle.exists and sandboxTitle.exists then
local compareUrl = mw.uri.fullUrl(
'Special:ComparePages',
{ page1 = templateTitle.prefixedText, page2 = sandboxTitle.prefixedText}
)
return tostring(compareUrl)
else
return nil
end
end
return env
end
----------------------------------------------------------------------------
-- Start box
----------------------------------------------------------------------------
p.startBox = makeInvokeFunc('_startBox')
function p._startBox(args, env)
--[[
-- This function generates the start box.
-- @args - a table of arguments passed by the user
-- @env - environment table containing title objects, etc., generated with p.getEnvironment
--
-- The actual work is done by p.makeStartBoxLinksData and p.renderStartBoxLinks which make
-- the [view] [edit] [history] [purge] links, and by p.makeStartBoxData and p.renderStartBox
-- which generate the box HTML.
--]]
env = env or p.getEnvironment(args)
local links
local content = args.content
if not content or args[1] then
-- No need to include the links if the documentation is on the template page itself.
local linksData = p.makeStartBoxLinksData(args, env)
if linksData then
links = p.renderStartBoxLinks(linksData)
end
end
-- Generate the start box html.
local data = p.makeStartBoxData(args, env, links)
if data then
return p.renderStartBox(data)
else
-- User specified no heading.
return nil
end
end
function p.makeStartBoxLinksData(args, env)
--[[
-- Does initial processing of data to make the [view] [edit] [history] [purge] links.
-- @args - a table of arguments passed by the user
-- @env - environment table containing title objects, etc., generated with p.getEnvironment
--
-- Messages:
-- 'view-link-display' --> 'view'
-- 'edit-link-display' --> 'edit'
-- 'history-link-display' --> 'history'
-- 'purge-link-display' --> 'purge'
-- 'module-preload' --> 'Template:Documentation/preload-module-doc'
-- 'docpage-preload' --> 'Template:Documentation/preload'
-- 'create-link-display' --> 'create'
--]]
local subjectSpace = env.subjectSpace
local title = env.title
local docTitle = env.docTitle
if not title or not docTitle then
return nil
end
if docTitle.isRedirect then
docTitle = docTitle.redirectTarget
end
local data = {}
data.title = title
data.docTitle = docTitle
-- View, display, edit, and purge links if /doc exists.
data.viewLinkDisplay = message('view-link-display')
data.editLinkDisplay = message('edit-link-display')
data.historyLinkDisplay = message('history-link-display')
data.purgeLinkDisplay = message('purge-link-display')
-- Create link if /doc doesn't exist.
local preload = args.preload
if not preload then
if subjectSpace == 828 then -- Module namespace
preload = message('module-preload')
else
preload = message('docpage-preload')
end
end
data.preload = preload
data.createLinkDisplay = message('create-link-display')
return data
end
function p.renderStartBoxLinks(data)
--[[
-- Generates the [view][edit][history][purge] or [create][purge] links from the data table.
-- @data - a table of data generated by p.makeStartBoxLinksData
--]]
local function escapeBrackets(s)
-- Escapes square brackets with HTML entities.
s = s:gsub('%[', '[') -- Replace square brackets with HTML entities.
s = s:gsub('%]', ']')
return s
end
local ret
local docTitle = data.docTitle
local title = data.title
local purgeLink = makeUrlLink(title:fullUrl{action = 'purge'}, data.purgeLinkDisplay)
if docTitle.exists then
local viewLink = makeWikilink(docTitle.prefixedText, data.viewLinkDisplay)
local editLink = makeUrlLink(docTitle:fullUrl{action = 'edit'}, data.editLinkDisplay)
local historyLink = makeUrlLink(docTitle:fullUrl{action = 'history'}, data.historyLinkDisplay)
ret = '[%s] [%s] [%s] [%s]'
ret = escapeBrackets(ret)
ret = mw.ustring.format(ret, viewLink, editLink, historyLink, purgeLink)
else
local createLink = makeUrlLink(docTitle:fullUrl{action = 'edit', preload = data.preload}, data.createLinkDisplay)
ret = '[%s] [%s]'
ret = escapeBrackets(ret)
ret = mw.ustring.format(ret, createLink, purgeLink)
end
return ret
end
function p.makeStartBoxData(args, env, links)
--[=[
-- Does initial processing of data to pass to the start-box render function, p.renderStartBox.
-- @args - a table of arguments passed by the user
-- @env - environment table containing title objects, etc., generated with p.getEnvironment
-- @links - a string containing the [view][edit][history][purge] links - could be nil if there's an error.
--
-- Messages:
-- 'documentation-icon-wikitext' --> '[[File:Test Template Info-Icon - Version (2).svg|50px|link=|alt=]]'
-- 'template-namespace-heading' --> 'Template documentation'
-- 'module-namespace-heading' --> 'Module documentation'
-- 'file-namespace-heading' --> 'Summary'
-- 'other-namespaces-heading' --> 'Documentation'
-- 'testcases-create-link-display' --> 'create'
--]=]
local subjectSpace = env.subjectSpace
if not subjectSpace then
-- Default to an "other namespaces" namespace, so that we get at least some output
-- if an error occurs.
subjectSpace = 2
end
local data = {}
-- Heading
local heading = args.heading -- Blank values are not removed.
if heading == '' then
-- Don't display the start box if the heading arg is defined but blank.
return nil
end
if heading then
data.heading = heading
elseif subjectSpace == 10 then -- Template namespace
data.heading = message('documentation-icon-wikitext') .. ' ' .. message('template-namespace-heading')
elseif subjectSpace == 828 then -- Module namespace
data.heading = message('documentation-icon-wikitext') .. ' ' .. message('module-namespace-heading')
elseif subjectSpace == 6 then -- File namespace
data.heading = message('file-namespace-heading')
else
data.heading = message('other-namespaces-heading')
end
-- Heading CSS
local headingStyle = args['heading-style']
if headingStyle then
data.headingStyleText = headingStyle
else
-- 'documentation-heading'
data.headingClass = message('main-div-heading-class')
end
-- Data for the [view][edit][history][purge] or [create] links.
if links then
-- 'mw-editsection-like plainlinks'
data.linksClass = message('start-box-link-classes')
data.links = links
end
return data
end
function p.renderStartBox(data)
-- Renders the start box html.
-- @data - a table of data generated by p.makeStartBoxData.
local sbox = mw.html.create('div')
sbox
-- 'documentation-startbox'
:addClass(message('start-box-class'))
:newline()
:tag('span')
:addClass(data.headingClass)
:attr('id', 'documentation-heading')
:cssText(data.headingStyleText)
:wikitext(data.heading)
local links = data.links
if links then
sbox:tag('span')
:addClass(data.linksClass)
:attr('id', data.linksId)
:wikitext(links)
end
return tostring(sbox)
end
----------------------------------------------------------------------------
-- Documentation content
----------------------------------------------------------------------------
p.content = makeInvokeFunc('_content')
function p._content(args, env)
-- Displays the documentation contents
-- @args - a table of arguments passed by the user
-- @env - environment table containing title objects, etc., generated with p.getEnvironment
env = env or p.getEnvironment(args)
local docTitle = env.docTitle
local content = args.content
if not content and docTitle and docTitle.exists then
content = args._content or mw.getCurrentFrame():expandTemplate{title = docTitle.prefixedText}
end
-- The line breaks below are necessary so that "=== Headings ===" at the start and end
-- of docs are interpreted correctly.
return '\n' .. (content or '') .. '\n'
end
p.contentTitle = makeInvokeFunc('_contentTitle')
function p._contentTitle(args, env)
env = env or p.getEnvironment(args)
local docTitle = env.docTitle
if not args.content and docTitle and docTitle.exists then
return docTitle.prefixedText
else
return ''
end
end
----------------------------------------------------------------------------
-- End box
----------------------------------------------------------------------------
p.endBox = makeInvokeFunc('_endBox')
function p._endBox(args, env)
--[=[
-- This function generates the end box (also known as the link box).
-- @args - a table of arguments passed by the user
-- @env - environment table containing title objects, etc., generated with p.getEnvironment
--
--]=]
-- Get environment data.
env = env or p.getEnvironment(args)
local subjectSpace = env.subjectSpace
local docTitle = env.docTitle
if not subjectSpace or not docTitle then
return nil
end
-- Check whether we should output the end box at all. Add the end
-- box by default if the documentation exists or if we are in the
-- user, module or template namespaces.
local linkBox = args['link box']
if linkBox == 'off'
or not (
docTitle.exists
or subjectSpace == 2
or subjectSpace == 828
or subjectSpace == 10
)
then
return nil
end
-- Assemble the link box.
local text = ''
if linkBox then
text = text .. linkBox
else
text = text .. (p.makeDocPageBlurb(args, env) or '') -- "This documentation is transcluded from [[Foo]]."
if subjectSpace == 2 or subjectSpace == 10 or subjectSpace == 828 then
-- We are in the user, template or module namespaces.
-- Add sandbox and testcases links.
-- "Editors can experiment in this template's sandbox and testcases pages."
text = text .. (p.makeExperimentBlurb(args, env) or '') .. '<br />'
if not args.content and not args[1] then
-- "Please add categories to the /doc subpage."
-- Don't show this message with inline docs or with an explicitly specified doc page,
-- as then it is unclear where to add the categories.
text = text .. (p.makeCategoriesBlurb(args, env) or '')
end
text = text .. ' ' .. (p.makeSubpagesBlurb(args, env) or '') --"Subpages of this template"
end
end
local box = mw.html.create('div')
-- 'documentation-metadata'
box:attr('role', 'note')
:addClass(message('end-box-class'))
-- 'plainlinks'
:addClass(message('end-box-plainlinks'))
:wikitext(text)
:done()
return '\n' .. tostring(box)
end
function p.makeDocPageBlurb(args, env)
--[=[
-- Makes the blurb "This documentation is transcluded from [[Template:Foo]] (edit, history)".
-- @args - a table of arguments passed by the user
-- @env - environment table containing title objects, etc., generated with p.getEnvironment
--
-- Messages:
-- 'edit-link-display' --> 'edit'
-- 'history-link-display' --> 'history'
-- 'transcluded-from-blurb' -->
-- 'The above [[Wikipedia:Template documentation|documentation]]
-- is [[Help:Transclusion|transcluded]] from $1.'
-- 'module-preload' --> 'Template:Documentation/preload-module-doc'
-- 'create-link-display' --> 'create'
-- 'create-module-doc-blurb' -->
-- 'You might want to $1 a documentation page for this [[Wikipedia:Lua|Scribunto module]].'
--]=]
local docTitle = env.docTitle
if not docTitle then
return nil
end
local ret
if docTitle.exists then
-- /doc exists; link to it.
local docLink = makeWikilink(docTitle.prefixedText)
local editUrl = docTitle:fullUrl{action = 'edit'}
local editDisplay = message('edit-link-display')
local editLink = makeUrlLink(editUrl, editDisplay)
local historyUrl = docTitle:fullUrl{action = 'history'}
local historyDisplay = message('history-link-display')
local historyLink = makeUrlLink(historyUrl, historyDisplay)
ret = message('transcluded-from-blurb', {docLink})
.. ' '
.. makeToolbar(editLink, historyLink)
.. '<br />'
elseif env.subjectSpace == 828 then
-- /doc does not exist; ask to create it.
local createUrl = docTitle:fullUrl{action = 'edit', preload = message('module-preload')}
local createDisplay = message('create-link-display')
local createLink = makeUrlLink(createUrl, createDisplay)
ret = message('create-module-doc-blurb', {createLink})
.. '<br />'
end
return ret
end
function p.makeExperimentBlurb(args, env)
--[[
-- Renders the text "Editors can experiment in this template's sandbox (edit | diff) and testcases (edit) pages."
-- @args - a table of arguments passed by the user
-- @env - environment table containing title objects, etc., generated with p.getEnvironment
--
-- Messages:
-- 'sandbox-link-display' --> 'sandbox'
-- 'sandbox-edit-link-display' --> 'edit'
-- 'compare-link-display' --> 'diff'
-- 'module-sandbox-preload' --> 'Template:Documentation/preload-module-sandbox'
-- 'template-sandbox-preload' --> 'Template:Documentation/preload-sandbox'
-- 'sandbox-create-link-display' --> 'create'
-- 'mirror-edit-summary' --> 'Create sandbox version of $1'
-- 'mirror-link-display' --> 'mirror'
-- 'mirror-link-preload' --> 'Template:Documentation/mirror'
-- 'sandbox-link-display' --> 'sandbox'
-- 'testcases-link-display' --> 'testcases'
-- 'testcases-edit-link-display'--> 'edit'
-- 'template-sandbox-preload' --> 'Template:Documentation/preload-sandbox'
-- 'testcases-create-link-display' --> 'create'
-- 'testcases-link-display' --> 'testcases'
-- 'testcases-edit-link-display' --> 'edit'
-- 'module-testcases-preload' --> 'Template:Documentation/preload-module-testcases'
-- 'template-testcases-preload' --> 'Template:Documentation/preload-testcases'
-- 'experiment-blurb-module' --> 'Editors can experiment in this module's $1 and $2 pages.'
-- 'experiment-blurb-template' --> 'Editors can experiment in this template's $1 and $2 pages.'
--]]
local subjectSpace = env.subjectSpace
local templateTitle = env.templateTitle
local sandboxTitle = env.sandboxTitle
local testcasesTitle = env.testcasesTitle
local templatePage = templateTitle.prefixedText
if not subjectSpace or not templateTitle or not sandboxTitle or not testcasesTitle then
return nil
end
-- Make links.
local sandboxLinks, testcasesLinks
if sandboxTitle.exists then
local sandboxPage = sandboxTitle.prefixedText
local sandboxDisplay = message('sandbox-link-display')
local sandboxLink = makeWikilink(sandboxPage, sandboxDisplay)
local sandboxEditUrl = sandboxTitle:fullUrl{action = 'edit'}
local sandboxEditDisplay = message('sandbox-edit-link-display')
local sandboxEditLink = makeUrlLink(sandboxEditUrl, sandboxEditDisplay)
local compareUrl = env.compareUrl
local compareLink
if compareUrl then
local compareDisplay = message('compare-link-display')
compareLink = makeUrlLink(compareUrl, compareDisplay)
end
sandboxLinks = sandboxLink .. ' ' .. makeToolbar(sandboxEditLink, compareLink)
else
local sandboxPreload
if subjectSpace == 828 then
sandboxPreload = message('module-sandbox-preload')
else
sandboxPreload = message('template-sandbox-preload')
end
local sandboxCreateUrl = sandboxTitle:fullUrl{action = 'edit', preload = sandboxPreload}
local sandboxCreateDisplay = message('sandbox-create-link-display')
local sandboxCreateLink = makeUrlLink(sandboxCreateUrl, sandboxCreateDisplay)
local mirrorSummary = message('mirror-edit-summary', {makeWikilink(templatePage)})
local mirrorPreload = message('mirror-link-preload')
local mirrorUrl = sandboxTitle:fullUrl{action = 'edit', preload = mirrorPreload, summary = mirrorSummary}
if subjectSpace == 828 then
mirrorUrl = sandboxTitle:fullUrl{action = 'edit', preload = templateTitle.prefixedText, summary = mirrorSummary}
end
local mirrorDisplay = message('mirror-link-display')
local mirrorLink = makeUrlLink(mirrorUrl, mirrorDisplay)
sandboxLinks = message('sandbox-link-display') .. ' ' .. makeToolbar(sandboxCreateLink, mirrorLink)
end
if testcasesTitle.exists then
local testcasesPage = testcasesTitle.prefixedText
local testcasesDisplay = message('testcases-link-display')
local testcasesLink = makeWikilink(testcasesPage, testcasesDisplay)
local testcasesEditUrl = testcasesTitle:fullUrl{action = 'edit'}
local testcasesEditDisplay = message('testcases-edit-link-display')
local testcasesEditLink = makeUrlLink(testcasesEditUrl, testcasesEditDisplay)
-- for Modules, add testcases run link if exists
if testcasesTitle.contentModel == "Scribunto" and testcasesTitle.talkPageTitle and testcasesTitle.talkPageTitle.exists then
local testcasesRunLinkDisplay = message('testcases-run-link-display')
local testcasesRunLink = makeWikilink(testcasesTitle.talkPageTitle.prefixedText, testcasesRunLinkDisplay)
testcasesLinks = testcasesLink .. ' ' .. makeToolbar(testcasesEditLink, testcasesRunLink)
else
testcasesLinks = testcasesLink .. ' ' .. makeToolbar(testcasesEditLink)
end
else
local testcasesPreload
if subjectSpace == 828 then
testcasesPreload = message('module-testcases-preload')
else
testcasesPreload = message('template-testcases-preload')
end
local testcasesCreateUrl = testcasesTitle:fullUrl{action = 'edit', preload = testcasesPreload}
local testcasesCreateDisplay = message('testcases-create-link-display')
local testcasesCreateLink = makeUrlLink(testcasesCreateUrl, testcasesCreateDisplay)
testcasesLinks = message('testcases-link-display') .. ' ' .. makeToolbar(testcasesCreateLink)
end
local messageName
if subjectSpace == 828 then
messageName = 'experiment-blurb-module'
else
messageName = 'experiment-blurb-template'
end
return message(messageName, {sandboxLinks, testcasesLinks})
end
function p.makeCategoriesBlurb(args, env)
--[[
-- Generates the text "Please add categories to the /doc subpage."
-- @args - a table of arguments passed by the user
-- @env - environment table containing title objects, etc., generated with p.getEnvironment
-- Messages:
-- 'doc-link-display' --> '/doc'
-- 'add-categories-blurb' --> 'Please add categories to the $1 subpage.'
--]]
local docTitle = env.docTitle
if not docTitle then
return nil
end
local docPathLink = makeWikilink(docTitle.prefixedText, message('doc-link-display'))
return message('add-categories-blurb', {docPathLink})
end
function p.makeSubpagesBlurb(args, env)
--[[
-- Generates the "Subpages of this template" link.
-- @args - a table of arguments passed by the user
-- @env - environment table containing title objects, etc., generated with p.getEnvironment
-- Messages:
-- 'template-pagetype' --> 'template'
-- 'module-pagetype' --> 'module'
-- 'default-pagetype' --> 'page'
-- 'subpages-link-display' --> 'Subpages of this $1'
--]]
local subjectSpace = env.subjectSpace
local templateTitle = env.templateTitle
if not subjectSpace or not templateTitle then
return nil
end
local pagetype
if subjectSpace == 10 then
pagetype = message('template-pagetype')
elseif subjectSpace == 828 then
pagetype = message('module-pagetype')
else
pagetype = message('default-pagetype')
end
local subpagesLink = makeWikilink(
'Special:PrefixIndex/' .. templateTitle.prefixedText .. '/',
message('subpages-link-display', {pagetype})
)
return message('subpages-blurb', {subpagesLink})
end
----------------------------------------------------------------------------
-- Tracking categories
----------------------------------------------------------------------------
function p.addTrackingCategories(env)
--[[
-- Check if {{documentation}} is transcluded on a /doc or /testcases page.
-- @env - environment table containing title objects, etc., generated with p.getEnvironment
-- Messages:
-- 'display-strange-usage-category' --> true
-- 'doc-subpage' --> 'doc'
-- 'testcases-subpage' --> 'testcases'
-- 'strange-usage-category' --> 'Wikipedia pages with strange ((documentation)) usage'
--
-- /testcases pages in the module namespace are not categorised, as they may have
-- {{documentation}} transcluded automatically.
--]]
local title = env.title
local subjectSpace = env.subjectSpace
if not title or not subjectSpace then
return nil
end
local subpage = title.subpageText
local ret = ''
if message('display-strange-usage-category', nil, 'boolean')
and (
subpage == message('doc-subpage')
or subjectSpace ~= 828 and subpage == message('testcases-subpage')
)
then
ret = ret .. makeCategoryLink(message('strange-usage-category'))
end
return ret
end
return p
78cc3a78f2b5dbb267fa16027c0800a22dbd3c42
7
5
2023-12-27T04:44:41Z
CreepersNeedHugs
2
Replaced content with "{{#invoke:documentation|main|_content={{ {{#invoke:documentation|contentTitle}}}}}}<noinclude>[[Category:Templates]]</noinclude>"
wikitext
text/x-wiki
{{#invoke:documentation|main|_content={{ {{#invoke:documentation|contentTitle}}}}}}<noinclude>[[Category:Templates]]</noinclude>
9885bb4fa99bf3d5b960e73606bbb8eed3026877
Module:Documentation
828
5
6
2023-12-27T04:43:17Z
CreepersNeedHugs
2
Created page with "-- This module implements {{documentation}}. -- Get required modules. local getArgs = require('Module:Arguments').getArgs -- Get the config table. local cfg = mw.loadData('Module:Documentation/config') local p = {} -- Often-used functions. local ugsub = mw.ustring.gsub ---------------------------------------------------------------------------- -- Helper functions -- -- These are defined as local functions, but are made available in the p -- table for testing purpos..."
Scribunto
text/plain
-- This module implements {{documentation}}.
-- Get required modules.
local getArgs = require('Module:Arguments').getArgs
-- Get the config table.
local cfg = mw.loadData('Module:Documentation/config')
local p = {}
-- Often-used functions.
local ugsub = mw.ustring.gsub
----------------------------------------------------------------------------
-- Helper functions
--
-- These are defined as local functions, but are made available in the p
-- table for testing purposes.
----------------------------------------------------------------------------
local function message(cfgKey, valArray, expectType)
--[[
-- Gets a message from the cfg table and formats it if appropriate.
-- The function raises an error if the value from the cfg table is not
-- of the type expectType. The default type for expectType is 'string'.
-- If the table valArray is present, strings such as $1, $2 etc. in the
-- message are substituted with values from the table keys [1], [2] etc.
-- For example, if the message "foo-message" had the value 'Foo $2 bar $1.',
-- message('foo-message', {'baz', 'qux'}) would return "Foo qux bar baz."
--]]
local msg = cfg[cfgKey]
expectType = expectType or 'string'
if type(msg) ~= expectType then
error('message: type error in message cfg.' .. cfgKey .. ' (' .. expectType .. ' expected, got ' .. type(msg) .. ')', 2)
end
if not valArray then
return msg
end
local function getMessageVal(match)
match = tonumber(match)
return valArray[match] or error('message: no value found for key $' .. match .. ' in message cfg.' .. cfgKey, 4)
end
return ugsub(msg, '$([1-9][0-9]*)', getMessageVal)
end
p.message = message
local function makeWikilink(page, display)
if display then
return mw.ustring.format('[[%s|%s]]', page, display)
else
return mw.ustring.format('[[%s]]', page)
end
end
p.makeWikilink = makeWikilink
local function makeCategoryLink(cat, sort)
local catns = mw.site.namespaces[14].name
return makeWikilink(catns .. ':' .. cat, sort)
end
p.makeCategoryLink = makeCategoryLink
local function makeUrlLink(url, display)
return mw.ustring.format('[%s %s]', url, display)
end
p.makeUrlLink = makeUrlLink
local function makeToolbar(...)
local ret = {}
local lim = select('#', ...)
if lim < 1 then
return nil
end
for i = 1, lim do
ret[#ret + 1] = select(i, ...)
end
-- 'documentation-toolbar'
return '<span class="' .. message('toolbar-class') .. '">('
.. table.concat(ret, ' | ') .. ')</span>'
end
p.makeToolbar = makeToolbar
----------------------------------------------------------------------------
-- Argument processing
----------------------------------------------------------------------------
local function makeInvokeFunc(funcName)
return function (frame)
local args = getArgs(frame, {
valueFunc = function (key, value)
if type(value) == 'string' then
value = value:match('^%s*(.-)%s*$') -- Remove whitespace.
if key == 'heading' or value ~= '' then
return value
else
return nil
end
else
return value
end
end
})
return p[funcName](args)
end
end
----------------------------------------------------------------------------
-- Entry points
----------------------------------------------------------------------------
function p.nonexistent(frame)
if mw.title.getCurrentTitle().subpageText == 'testcases' then
return frame:expandTemplate{title = 'module test cases notice'}
else
return p.main(frame)
end
end
p.main = makeInvokeFunc('_main')
function p._main(args)
--[[
-- This function defines logic flow for the module.
-- @args - table of arguments passed by the user
--]]
local env = p.getEnvironment(args)
local root = mw.html.create()
root
:tag('div')
-- 'documentation-container'
:addClass(message('container'))
:attr('role', 'complementary')
:attr('aria-labelledby', args.heading ~= '' and 'documentation-heading' or nil)
:attr('aria-label', args.heading == '' and 'Documentation' or nil)
:newline()
:tag('div')
-- 'documentation'
:addClass(message('main-div-classes'))
:newline()
:wikitext(p._startBox(args, env))
:wikitext(p._content(args, env))
:tag('div')
-- 'documentation-clear'
:addClass(message('clear'))
:done()
:newline()
:done()
:wikitext(p._endBox(args, env))
:done()
:wikitext(p.addTrackingCategories(env))
-- 'Module:Documentation/styles.css'
return mw.getCurrentFrame():extensionTag (
'templatestyles', '', {src=cfg['templatestyles']
}) .. tostring(root)
end
----------------------------------------------------------------------------
-- Environment settings
----------------------------------------------------------------------------
function p.getEnvironment(args)
--[[
-- Returns a table with information about the environment, including title
-- objects and other namespace- or path-related data.
-- @args - table of arguments passed by the user
--
-- Title objects include:
-- env.title - the page we are making documentation for (usually the current title)
-- env.templateTitle - the template (or module, file, etc.)
-- env.docTitle - the /doc subpage.
-- env.sandboxTitle - the /sandbox subpage.
-- env.testcasesTitle - the /testcases subpage.
--
-- Data includes:
-- env.subjectSpace - the number of the title's subject namespace.
-- env.docSpace - the number of the namespace the title puts its documentation in.
-- env.docpageBase - the text of the base page of the /doc, /sandbox and /testcases pages, with namespace.
-- env.compareUrl - URL of the Special:ComparePages page comparing the sandbox with the template.
--
-- All table lookups are passed through pcall so that errors are caught. If an error occurs, the value
-- returned will be nil.
--]]
local env, envFuncs = {}, {}
-- Set up the metatable. If triggered we call the corresponding function in the envFuncs table. The value
-- returned by that function is memoized in the env table so that we don't call any of the functions
-- more than once. (Nils won't be memoized.)
setmetatable(env, {
__index = function (t, key)
local envFunc = envFuncs[key]
if envFunc then
local success, val = pcall(envFunc)
if success then
env[key] = val -- Memoise the value.
return val
end
end
return nil
end
})
function envFuncs.title()
-- The title object for the current page, or a test page passed with args.page.
local title
local titleArg = args.page
if titleArg then
title = mw.title.new(titleArg)
else
title = mw.title.getCurrentTitle()
end
return title
end
function envFuncs.templateTitle()
--[[
-- The template (or module, etc.) title object.
-- Messages:
-- 'sandbox-subpage' --> 'sandbox'
-- 'testcases-subpage' --> 'testcases'
--]]
local subjectSpace = env.subjectSpace
local title = env.title
local subpage = title.subpageText
if subpage == message('sandbox-subpage') or subpage == message('testcases-subpage') then
return mw.title.makeTitle(subjectSpace, title.baseText)
else
return mw.title.makeTitle(subjectSpace, title.text)
end
end
function envFuncs.docTitle()
--[[
-- Title object of the /doc subpage.
-- Messages:
-- 'doc-subpage' --> 'doc'
--]]
local title = env.title
local docname = args[1] -- User-specified doc page.
local docpage
if docname then
docpage = docname
else
docpage = env.docpageBase .. '/' .. message('doc-subpage')
end
return mw.title.new(docpage)
end
function envFuncs.sandboxTitle()
--[[
-- Title object for the /sandbox subpage.
-- Messages:
-- 'sandbox-subpage' --> 'sandbox'
--]]
return mw.title.new(env.docpageBase .. '/' .. message('sandbox-subpage'))
end
function envFuncs.testcasesTitle()
--[[
-- Title object for the /testcases subpage.
-- Messages:
-- 'testcases-subpage' --> 'testcases'
--]]
return mw.title.new(env.docpageBase .. '/' .. message('testcases-subpage'))
end
function envFuncs.subjectSpace()
-- The subject namespace number.
return mw.site.namespaces[env.title.namespace].subject.id
end
function envFuncs.docSpace()
-- The documentation namespace number. For most namespaces this is the
-- same as the subject namespace. However, pages in the Article, File,
-- MediaWiki or Category namespaces must have their /doc, /sandbox and
-- /testcases pages in talk space.
local subjectSpace = env.subjectSpace
if subjectSpace == 0 or subjectSpace == 6 or subjectSpace == 8 or subjectSpace == 14 then
return subjectSpace + 1
else
return subjectSpace
end
end
function envFuncs.docpageBase()
-- The base page of the /doc, /sandbox, and /testcases subpages.
-- For some namespaces this is the talk page, rather than the template page.
local templateTitle = env.templateTitle
local docSpace = env.docSpace
local docSpaceText = mw.site.namespaces[docSpace].name
-- Assemble the link. docSpace is never the main namespace, so we can hardcode the colon.
return docSpaceText .. ':' .. templateTitle.text
end
function envFuncs.compareUrl()
-- Diff link between the sandbox and the main template using [[Special:ComparePages]].
local templateTitle = env.templateTitle
local sandboxTitle = env.sandboxTitle
if templateTitle.exists and sandboxTitle.exists then
local compareUrl = mw.uri.fullUrl(
'Special:ComparePages',
{ page1 = templateTitle.prefixedText, page2 = sandboxTitle.prefixedText}
)
return tostring(compareUrl)
else
return nil
end
end
return env
end
----------------------------------------------------------------------------
-- Start box
----------------------------------------------------------------------------
p.startBox = makeInvokeFunc('_startBox')
function p._startBox(args, env)
--[[
-- This function generates the start box.
-- @args - a table of arguments passed by the user
-- @env - environment table containing title objects, etc., generated with p.getEnvironment
--
-- The actual work is done by p.makeStartBoxLinksData and p.renderStartBoxLinks which make
-- the [view] [edit] [history] [purge] links, and by p.makeStartBoxData and p.renderStartBox
-- which generate the box HTML.
--]]
env = env or p.getEnvironment(args)
local links
local content = args.content
if not content or args[1] then
-- No need to include the links if the documentation is on the template page itself.
local linksData = p.makeStartBoxLinksData(args, env)
if linksData then
links = p.renderStartBoxLinks(linksData)
end
end
-- Generate the start box html.
local data = p.makeStartBoxData(args, env, links)
if data then
return p.renderStartBox(data)
else
-- User specified no heading.
return nil
end
end
function p.makeStartBoxLinksData(args, env)
--[[
-- Does initial processing of data to make the [view] [edit] [history] [purge] links.
-- @args - a table of arguments passed by the user
-- @env - environment table containing title objects, etc., generated with p.getEnvironment
--
-- Messages:
-- 'view-link-display' --> 'view'
-- 'edit-link-display' --> 'edit'
-- 'history-link-display' --> 'history'
-- 'purge-link-display' --> 'purge'
-- 'module-preload' --> 'Template:Documentation/preload-module-doc'
-- 'docpage-preload' --> 'Template:Documentation/preload'
-- 'create-link-display' --> 'create'
--]]
local subjectSpace = env.subjectSpace
local title = env.title
local docTitle = env.docTitle
if not title or not docTitle then
return nil
end
if docTitle.isRedirect then
docTitle = docTitle.redirectTarget
end
local data = {}
data.title = title
data.docTitle = docTitle
-- View, display, edit, and purge links if /doc exists.
data.viewLinkDisplay = message('view-link-display')
data.editLinkDisplay = message('edit-link-display')
data.historyLinkDisplay = message('history-link-display')
data.purgeLinkDisplay = message('purge-link-display')
-- Create link if /doc doesn't exist.
local preload = args.preload
if not preload then
if subjectSpace == 828 then -- Module namespace
preload = message('module-preload')
else
preload = message('docpage-preload')
end
end
data.preload = preload
data.createLinkDisplay = message('create-link-display')
return data
end
function p.renderStartBoxLinks(data)
--[[
-- Generates the [view][edit][history][purge] or [create][purge] links from the data table.
-- @data - a table of data generated by p.makeStartBoxLinksData
--]]
local function escapeBrackets(s)
-- Escapes square brackets with HTML entities.
s = s:gsub('%[', '[') -- Replace square brackets with HTML entities.
s = s:gsub('%]', ']')
return s
end
local ret
local docTitle = data.docTitle
local title = data.title
local purgeLink = makeUrlLink(title:fullUrl{action = 'purge'}, data.purgeLinkDisplay)
if docTitle.exists then
local viewLink = makeWikilink(docTitle.prefixedText, data.viewLinkDisplay)
local editLink = makeUrlLink(docTitle:fullUrl{action = 'edit'}, data.editLinkDisplay)
local historyLink = makeUrlLink(docTitle:fullUrl{action = 'history'}, data.historyLinkDisplay)
ret = '[%s] [%s] [%s] [%s]'
ret = escapeBrackets(ret)
ret = mw.ustring.format(ret, viewLink, editLink, historyLink, purgeLink)
else
local createLink = makeUrlLink(docTitle:fullUrl{action = 'edit', preload = data.preload}, data.createLinkDisplay)
ret = '[%s] [%s]'
ret = escapeBrackets(ret)
ret = mw.ustring.format(ret, createLink, purgeLink)
end
return ret
end
function p.makeStartBoxData(args, env, links)
--[=[
-- Does initial processing of data to pass to the start-box render function, p.renderStartBox.
-- @args - a table of arguments passed by the user
-- @env - environment table containing title objects, etc., generated with p.getEnvironment
-- @links - a string containing the [view][edit][history][purge] links - could be nil if there's an error.
--
-- Messages:
-- 'documentation-icon-wikitext' --> '[[File:Test Template Info-Icon - Version (2).svg|50px|link=|alt=]]'
-- 'template-namespace-heading' --> 'Template documentation'
-- 'module-namespace-heading' --> 'Module documentation'
-- 'file-namespace-heading' --> 'Summary'
-- 'other-namespaces-heading' --> 'Documentation'
-- 'testcases-create-link-display' --> 'create'
--]=]
local subjectSpace = env.subjectSpace
if not subjectSpace then
-- Default to an "other namespaces" namespace, so that we get at least some output
-- if an error occurs.
subjectSpace = 2
end
local data = {}
-- Heading
local heading = args.heading -- Blank values are not removed.
if heading == '' then
-- Don't display the start box if the heading arg is defined but blank.
return nil
end
if heading then
data.heading = heading
elseif subjectSpace == 10 then -- Template namespace
data.heading = message('documentation-icon-wikitext') .. ' ' .. message('template-namespace-heading')
elseif subjectSpace == 828 then -- Module namespace
data.heading = message('documentation-icon-wikitext') .. ' ' .. message('module-namespace-heading')
elseif subjectSpace == 6 then -- File namespace
data.heading = message('file-namespace-heading')
else
data.heading = message('other-namespaces-heading')
end
-- Heading CSS
local headingStyle = args['heading-style']
if headingStyle then
data.headingStyleText = headingStyle
else
-- 'documentation-heading'
data.headingClass = message('main-div-heading-class')
end
-- Data for the [view][edit][history][purge] or [create] links.
if links then
-- 'mw-editsection-like plainlinks'
data.linksClass = message('start-box-link-classes')
data.links = links
end
return data
end
function p.renderStartBox(data)
-- Renders the start box html.
-- @data - a table of data generated by p.makeStartBoxData.
local sbox = mw.html.create('div')
sbox
-- 'documentation-startbox'
:addClass(message('start-box-class'))
:newline()
:tag('span')
:addClass(data.headingClass)
:attr('id', 'documentation-heading')
:cssText(data.headingStyleText)
:wikitext(data.heading)
local links = data.links
if links then
sbox:tag('span')
:addClass(data.linksClass)
:attr('id', data.linksId)
:wikitext(links)
end
return tostring(sbox)
end
----------------------------------------------------------------------------
-- Documentation content
----------------------------------------------------------------------------
p.content = makeInvokeFunc('_content')
function p._content(args, env)
-- Displays the documentation contents
-- @args - a table of arguments passed by the user
-- @env - environment table containing title objects, etc., generated with p.getEnvironment
env = env or p.getEnvironment(args)
local docTitle = env.docTitle
local content = args.content
if not content and docTitle and docTitle.exists then
content = args._content or mw.getCurrentFrame():expandTemplate{title = docTitle.prefixedText}
end
-- The line breaks below are necessary so that "=== Headings ===" at the start and end
-- of docs are interpreted correctly.
return '\n' .. (content or '') .. '\n'
end
p.contentTitle = makeInvokeFunc('_contentTitle')
function p._contentTitle(args, env)
env = env or p.getEnvironment(args)
local docTitle = env.docTitle
if not args.content and docTitle and docTitle.exists then
return docTitle.prefixedText
else
return ''
end
end
----------------------------------------------------------------------------
-- End box
----------------------------------------------------------------------------
p.endBox = makeInvokeFunc('_endBox')
function p._endBox(args, env)
--[=[
-- This function generates the end box (also known as the link box).
-- @args - a table of arguments passed by the user
-- @env - environment table containing title objects, etc., generated with p.getEnvironment
--
--]=]
-- Get environment data.
env = env or p.getEnvironment(args)
local subjectSpace = env.subjectSpace
local docTitle = env.docTitle
if not subjectSpace or not docTitle then
return nil
end
-- Check whether we should output the end box at all. Add the end
-- box by default if the documentation exists or if we are in the
-- user, module or template namespaces.
local linkBox = args['link box']
if linkBox == 'off'
or not (
docTitle.exists
or subjectSpace == 2
or subjectSpace == 828
or subjectSpace == 10
)
then
return nil
end
-- Assemble the link box.
local text = ''
if linkBox then
text = text .. linkBox
else
text = text .. (p.makeDocPageBlurb(args, env) or '') -- "This documentation is transcluded from [[Foo]]."
if subjectSpace == 2 or subjectSpace == 10 or subjectSpace == 828 then
-- We are in the user, template or module namespaces.
-- Add sandbox and testcases links.
-- "Editors can experiment in this template's sandbox and testcases pages."
text = text .. (p.makeExperimentBlurb(args, env) or '') .. '<br />'
if not args.content and not args[1] then
-- "Please add categories to the /doc subpage."
-- Don't show this message with inline docs or with an explicitly specified doc page,
-- as then it is unclear where to add the categories.
text = text .. (p.makeCategoriesBlurb(args, env) or '')
end
text = text .. ' ' .. (p.makeSubpagesBlurb(args, env) or '') --"Subpages of this template"
end
end
local box = mw.html.create('div')
-- 'documentation-metadata'
box:attr('role', 'note')
:addClass(message('end-box-class'))
-- 'plainlinks'
:addClass(message('end-box-plainlinks'))
:wikitext(text)
:done()
return '\n' .. tostring(box)
end
function p.makeDocPageBlurb(args, env)
--[=[
-- Makes the blurb "This documentation is transcluded from [[Template:Foo]] (edit, history)".
-- @args - a table of arguments passed by the user
-- @env - environment table containing title objects, etc., generated with p.getEnvironment
--
-- Messages:
-- 'edit-link-display' --> 'edit'
-- 'history-link-display' --> 'history'
-- 'transcluded-from-blurb' -->
-- 'The above [[Wikipedia:Template documentation|documentation]]
-- is [[Help:Transclusion|transcluded]] from $1.'
-- 'module-preload' --> 'Template:Documentation/preload-module-doc'
-- 'create-link-display' --> 'create'
-- 'create-module-doc-blurb' -->
-- 'You might want to $1 a documentation page for this [[Wikipedia:Lua|Scribunto module]].'
--]=]
local docTitle = env.docTitle
if not docTitle then
return nil
end
local ret
if docTitle.exists then
-- /doc exists; link to it.
local docLink = makeWikilink(docTitle.prefixedText)
local editUrl = docTitle:fullUrl{action = 'edit'}
local editDisplay = message('edit-link-display')
local editLink = makeUrlLink(editUrl, editDisplay)
local historyUrl = docTitle:fullUrl{action = 'history'}
local historyDisplay = message('history-link-display')
local historyLink = makeUrlLink(historyUrl, historyDisplay)
ret = message('transcluded-from-blurb', {docLink})
.. ' '
.. makeToolbar(editLink, historyLink)
.. '<br />'
elseif env.subjectSpace == 828 then
-- /doc does not exist; ask to create it.
local createUrl = docTitle:fullUrl{action = 'edit', preload = message('module-preload')}
local createDisplay = message('create-link-display')
local createLink = makeUrlLink(createUrl, createDisplay)
ret = message('create-module-doc-blurb', {createLink})
.. '<br />'
end
return ret
end
function p.makeExperimentBlurb(args, env)
--[[
-- Renders the text "Editors can experiment in this template's sandbox (edit | diff) and testcases (edit) pages."
-- @args - a table of arguments passed by the user
-- @env - environment table containing title objects, etc., generated with p.getEnvironment
--
-- Messages:
-- 'sandbox-link-display' --> 'sandbox'
-- 'sandbox-edit-link-display' --> 'edit'
-- 'compare-link-display' --> 'diff'
-- 'module-sandbox-preload' --> 'Template:Documentation/preload-module-sandbox'
-- 'template-sandbox-preload' --> 'Template:Documentation/preload-sandbox'
-- 'sandbox-create-link-display' --> 'create'
-- 'mirror-edit-summary' --> 'Create sandbox version of $1'
-- 'mirror-link-display' --> 'mirror'
-- 'mirror-link-preload' --> 'Template:Documentation/mirror'
-- 'sandbox-link-display' --> 'sandbox'
-- 'testcases-link-display' --> 'testcases'
-- 'testcases-edit-link-display'--> 'edit'
-- 'template-sandbox-preload' --> 'Template:Documentation/preload-sandbox'
-- 'testcases-create-link-display' --> 'create'
-- 'testcases-link-display' --> 'testcases'
-- 'testcases-edit-link-display' --> 'edit'
-- 'module-testcases-preload' --> 'Template:Documentation/preload-module-testcases'
-- 'template-testcases-preload' --> 'Template:Documentation/preload-testcases'
-- 'experiment-blurb-module' --> 'Editors can experiment in this module's $1 and $2 pages.'
-- 'experiment-blurb-template' --> 'Editors can experiment in this template's $1 and $2 pages.'
--]]
local subjectSpace = env.subjectSpace
local templateTitle = env.templateTitle
local sandboxTitle = env.sandboxTitle
local testcasesTitle = env.testcasesTitle
local templatePage = templateTitle.prefixedText
if not subjectSpace or not templateTitle or not sandboxTitle or not testcasesTitle then
return nil
end
-- Make links.
local sandboxLinks, testcasesLinks
if sandboxTitle.exists then
local sandboxPage = sandboxTitle.prefixedText
local sandboxDisplay = message('sandbox-link-display')
local sandboxLink = makeWikilink(sandboxPage, sandboxDisplay)
local sandboxEditUrl = sandboxTitle:fullUrl{action = 'edit'}
local sandboxEditDisplay = message('sandbox-edit-link-display')
local sandboxEditLink = makeUrlLink(sandboxEditUrl, sandboxEditDisplay)
local compareUrl = env.compareUrl
local compareLink
if compareUrl then
local compareDisplay = message('compare-link-display')
compareLink = makeUrlLink(compareUrl, compareDisplay)
end
sandboxLinks = sandboxLink .. ' ' .. makeToolbar(sandboxEditLink, compareLink)
else
local sandboxPreload
if subjectSpace == 828 then
sandboxPreload = message('module-sandbox-preload')
else
sandboxPreload = message('template-sandbox-preload')
end
local sandboxCreateUrl = sandboxTitle:fullUrl{action = 'edit', preload = sandboxPreload}
local sandboxCreateDisplay = message('sandbox-create-link-display')
local sandboxCreateLink = makeUrlLink(sandboxCreateUrl, sandboxCreateDisplay)
local mirrorSummary = message('mirror-edit-summary', {makeWikilink(templatePage)})
local mirrorPreload = message('mirror-link-preload')
local mirrorUrl = sandboxTitle:fullUrl{action = 'edit', preload = mirrorPreload, summary = mirrorSummary}
if subjectSpace == 828 then
mirrorUrl = sandboxTitle:fullUrl{action = 'edit', preload = templateTitle.prefixedText, summary = mirrorSummary}
end
local mirrorDisplay = message('mirror-link-display')
local mirrorLink = makeUrlLink(mirrorUrl, mirrorDisplay)
sandboxLinks = message('sandbox-link-display') .. ' ' .. makeToolbar(sandboxCreateLink, mirrorLink)
end
if testcasesTitle.exists then
local testcasesPage = testcasesTitle.prefixedText
local testcasesDisplay = message('testcases-link-display')
local testcasesLink = makeWikilink(testcasesPage, testcasesDisplay)
local testcasesEditUrl = testcasesTitle:fullUrl{action = 'edit'}
local testcasesEditDisplay = message('testcases-edit-link-display')
local testcasesEditLink = makeUrlLink(testcasesEditUrl, testcasesEditDisplay)
-- for Modules, add testcases run link if exists
if testcasesTitle.contentModel == "Scribunto" and testcasesTitle.talkPageTitle and testcasesTitle.talkPageTitle.exists then
local testcasesRunLinkDisplay = message('testcases-run-link-display')
local testcasesRunLink = makeWikilink(testcasesTitle.talkPageTitle.prefixedText, testcasesRunLinkDisplay)
testcasesLinks = testcasesLink .. ' ' .. makeToolbar(testcasesEditLink, testcasesRunLink)
else
testcasesLinks = testcasesLink .. ' ' .. makeToolbar(testcasesEditLink)
end
else
local testcasesPreload
if subjectSpace == 828 then
testcasesPreload = message('module-testcases-preload')
else
testcasesPreload = message('template-testcases-preload')
end
local testcasesCreateUrl = testcasesTitle:fullUrl{action = 'edit', preload = testcasesPreload}
local testcasesCreateDisplay = message('testcases-create-link-display')
local testcasesCreateLink = makeUrlLink(testcasesCreateUrl, testcasesCreateDisplay)
testcasesLinks = message('testcases-link-display') .. ' ' .. makeToolbar(testcasesCreateLink)
end
local messageName
if subjectSpace == 828 then
messageName = 'experiment-blurb-module'
else
messageName = 'experiment-blurb-template'
end
return message(messageName, {sandboxLinks, testcasesLinks})
end
function p.makeCategoriesBlurb(args, env)
--[[
-- Generates the text "Please add categories to the /doc subpage."
-- @args - a table of arguments passed by the user
-- @env - environment table containing title objects, etc., generated with p.getEnvironment
-- Messages:
-- 'doc-link-display' --> '/doc'
-- 'add-categories-blurb' --> 'Please add categories to the $1 subpage.'
--]]
local docTitle = env.docTitle
if not docTitle then
return nil
end
local docPathLink = makeWikilink(docTitle.prefixedText, message('doc-link-display'))
return message('add-categories-blurb', {docPathLink})
end
function p.makeSubpagesBlurb(args, env)
--[[
-- Generates the "Subpages of this template" link.
-- @args - a table of arguments passed by the user
-- @env - environment table containing title objects, etc., generated with p.getEnvironment
-- Messages:
-- 'template-pagetype' --> 'template'
-- 'module-pagetype' --> 'module'
-- 'default-pagetype' --> 'page'
-- 'subpages-link-display' --> 'Subpages of this $1'
--]]
local subjectSpace = env.subjectSpace
local templateTitle = env.templateTitle
if not subjectSpace or not templateTitle then
return nil
end
local pagetype
if subjectSpace == 10 then
pagetype = message('template-pagetype')
elseif subjectSpace == 828 then
pagetype = message('module-pagetype')
else
pagetype = message('default-pagetype')
end
local subpagesLink = makeWikilink(
'Special:PrefixIndex/' .. templateTitle.prefixedText .. '/',
message('subpages-link-display', {pagetype})
)
return message('subpages-blurb', {subpagesLink})
end
----------------------------------------------------------------------------
-- Tracking categories
----------------------------------------------------------------------------
function p.addTrackingCategories(env)
--[[
-- Check if {{documentation}} is transcluded on a /doc or /testcases page.
-- @env - environment table containing title objects, etc., generated with p.getEnvironment
-- Messages:
-- 'display-strange-usage-category' --> true
-- 'doc-subpage' --> 'doc'
-- 'testcases-subpage' --> 'testcases'
-- 'strange-usage-category' --> 'Wikipedia pages with strange ((documentation)) usage'
--
-- /testcases pages in the module namespace are not categorised, as they may have
-- {{documentation}} transcluded automatically.
--]]
local title = env.title
local subjectSpace = env.subjectSpace
if not title or not subjectSpace then
return nil
end
local subpage = title.subpageText
local ret = ''
if message('display-strange-usage-category', nil, 'boolean')
and (
subpage == message('doc-subpage')
or subjectSpace ~= 828 and subpage == message('testcases-subpage')
)
then
ret = ret .. makeCategoryLink(message('strange-usage-category'))
end
return ret
end
return p
78cc3a78f2b5dbb267fa16027c0800a22dbd3c42
Module:Arguments
828
6
8
2023-12-27T04:45:40Z
CreepersNeedHugs
2
Created page with "-- This module provides easy processing of arguments passed to Scribunto from -- #invoke. It is intended for use by other Lua modules, and should not be -- called from #invoke directly. local libraryUtil = require('libraryUtil') local checkType = libraryUtil.checkType local arguments = {} -- Generate four different tidyVal functions, so that we don't have to check the -- options every time we call it. local function tidyValDefault(key, val) if type(val) == 'string'..."
Scribunto
text/plain
-- This module provides easy processing of arguments passed to Scribunto from
-- #invoke. It is intended for use by other Lua modules, and should not be
-- called from #invoke directly.
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local arguments = {}
-- Generate four different tidyVal functions, so that we don't have to check the
-- options every time we call it.
local function tidyValDefault(key, val)
if type(val) == 'string' then
val = val:match('^%s*(.-)%s*$')
if val == '' then
return nil
else
return val
end
else
return val
end
end
local function tidyValTrimOnly(key, val)
if type(val) == 'string' then
return val:match('^%s*(.-)%s*$')
else
return val
end
end
local function tidyValRemoveBlanksOnly(key, val)
if type(val) == 'string' then
if val:find('%S') then
return val
else
return nil
end
else
return val
end
end
local function tidyValNoChange(key, val)
return val
end
local function matchesTitle(given, title)
local tp = type( given )
return (tp == 'string' or tp == 'number') and mw.title.new( given ).prefixedText == title
end
local translate_mt = { __index = function(t, k) return k end }
function arguments.getArgs(frame, options)
checkType('getArgs', 1, frame, 'table', true)
checkType('getArgs', 2, options, 'table', true)
frame = frame or {}
options = options or {}
--[[
-- Set up argument translation.
--]]
options.translate = options.translate or {}
if getmetatable(options.translate) == nil then
setmetatable(options.translate, translate_mt)
end
if options.backtranslate == nil then
options.backtranslate = {}
for k,v in pairs(options.translate) do
options.backtranslate[v] = k
end
end
if options.backtranslate and getmetatable(options.backtranslate) == nil then
setmetatable(options.backtranslate, {
__index = function(t, k)
if options.translate[k] ~= k then
return nil
else
return k
end
end
})
end
--[[
-- Get the argument tables. If we were passed a valid frame object, get the
-- frame arguments (fargs) and the parent frame arguments (pargs), depending
-- on the options set and on the parent frame's availability. If we weren't
-- passed a valid frame object, we are being called from another Lua module
-- or from the debug console, so assume that we were passed a table of args
-- directly, and assign it to a new variable (luaArgs).
--]]
local fargs, pargs, luaArgs
if type(frame.args) == 'table' and type(frame.getParent) == 'function' then
if options.wrappers then
--[[
-- The wrappers option makes Module:Arguments look up arguments in
-- either the frame argument table or the parent argument table, but
-- not both. This means that users can use either the #invoke syntax
-- or a wrapper template without the loss of performance associated
-- with looking arguments up in both the frame and the parent frame.
-- Module:Arguments will look up arguments in the parent frame
-- if it finds the parent frame's title in options.wrapper;
-- otherwise it will look up arguments in the frame object passed
-- to getArgs.
--]]
local parent = frame:getParent()
if not parent then
fargs = frame.args
else
local title = parent:getTitle():gsub('/sandbox$', '')
local found = false
if matchesTitle(options.wrappers, title) then
found = true
elseif type(options.wrappers) == 'table' then
for _,v in pairs(options.wrappers) do
if matchesTitle(v, title) then
found = true
break
end
end
end
-- We test for false specifically here so that nil (the default) acts like true.
if found or options.frameOnly == false then
pargs = parent.args
end
if not found or options.parentOnly == false then
fargs = frame.args
end
end
else
-- options.wrapper isn't set, so check the other options.
if not options.parentOnly then
fargs = frame.args
end
if not options.frameOnly then
local parent = frame:getParent()
pargs = parent and parent.args or nil
end
end
if options.parentFirst then
fargs, pargs = pargs, fargs
end
else
luaArgs = frame
end
-- Set the order of precedence of the argument tables. If the variables are
-- nil, nothing will be added to the table, which is how we avoid clashes
-- between the frame/parent args and the Lua args.
local argTables = {fargs}
argTables[#argTables + 1] = pargs
argTables[#argTables + 1] = luaArgs
--[[
-- Generate the tidyVal function. If it has been specified by the user, we
-- use that; if not, we choose one of four functions depending on the
-- options chosen. This is so that we don't have to call the options table
-- every time the function is called.
--]]
local tidyVal = options.valueFunc
if tidyVal then
if type(tidyVal) ~= 'function' then
error(
"bad value assigned to option 'valueFunc'"
.. '(function expected, got '
.. type(tidyVal)
.. ')',
2
)
end
elseif options.trim ~= false then
if options.removeBlanks ~= false then
tidyVal = tidyValDefault
else
tidyVal = tidyValTrimOnly
end
else
if options.removeBlanks ~= false then
tidyVal = tidyValRemoveBlanksOnly
else
tidyVal = tidyValNoChange
end
end
--[[
-- Set up the args, metaArgs and nilArgs tables. args will be the one
-- accessed from functions, and metaArgs will hold the actual arguments. Nil
-- arguments are memoized in nilArgs, and the metatable connects all of them
-- together.
--]]
local args, metaArgs, nilArgs, metatable = {}, {}, {}, {}
setmetatable(args, metatable)
local function mergeArgs(tables)
--[[
-- Accepts multiple tables as input and merges their keys and values
-- into one table. If a value is already present it is not overwritten;
-- tables listed earlier have precedence. We are also memoizing nil
-- values, which can be overwritten if they are 's' (soft).
--]]
for _, t in ipairs(tables) do
for key, val in pairs(t) do
if metaArgs[key] == nil and nilArgs[key] ~= 'h' then
local tidiedVal = tidyVal(key, val)
if tidiedVal == nil then
nilArgs[key] = 's'
else
metaArgs[key] = tidiedVal
end
end
end
end
end
--[[
-- Define metatable behaviour. Arguments are memoized in the metaArgs table,
-- and are only fetched from the argument tables once. Fetching arguments
-- from the argument tables is the most resource-intensive step in this
-- module, so we try and avoid it where possible. For this reason, nil
-- arguments are also memoized, in the nilArgs table. Also, we keep a record
-- in the metatable of when pairs and ipairs have been called, so we do not
-- run pairs and ipairs on the argument tables more than once. We also do
-- not run ipairs on fargs and pargs if pairs has already been run, as all
-- the arguments will already have been copied over.
--]]
metatable.__index = function (t, key)
--[[
-- Fetches an argument when the args table is indexed. First we check
-- to see if the value is memoized, and if not we try and fetch it from
-- the argument tables. When we check memoization, we need to check
-- metaArgs before nilArgs, as both can be non-nil at the same time.
-- If the argument is not present in metaArgs, we also check whether
-- pairs has been run yet. If pairs has already been run, we return nil.
-- This is because all the arguments will have already been copied into
-- metaArgs by the mergeArgs function, meaning that any other arguments
-- must be nil.
--]]
if type(key) == 'string' then
key = options.translate[key]
end
local val = metaArgs[key]
if val ~= nil then
return val
elseif metatable.donePairs or nilArgs[key] then
return nil
end
for _, argTable in ipairs(argTables) do
local argTableVal = tidyVal(key, argTable[key])
if argTableVal ~= nil then
metaArgs[key] = argTableVal
return argTableVal
end
end
nilArgs[key] = 'h'
return nil
end
metatable.__newindex = function (t, key, val)
-- This function is called when a module tries to add a new value to the
-- args table, or tries to change an existing value.
if type(key) == 'string' then
key = options.translate[key]
end
if options.readOnly then
error(
'could not write to argument table key "'
.. tostring(key)
.. '"; the table is read-only',
2
)
elseif options.noOverwrite and args[key] ~= nil then
error(
'could not write to argument table key "'
.. tostring(key)
.. '"; overwriting existing arguments is not permitted',
2
)
elseif val == nil then
--[[
-- If the argument is to be overwritten with nil, we need to erase
-- the value in metaArgs, so that __index, __pairs and __ipairs do
-- not use a previous existing value, if present; and we also need
-- to memoize the nil in nilArgs, so that the value isn't looked
-- up in the argument tables if it is accessed again.
--]]
metaArgs[key] = nil
nilArgs[key] = 'h'
else
metaArgs[key] = val
end
end
local function translatenext(invariant)
local k, v = next(invariant.t, invariant.k)
invariant.k = k
if k == nil then
return nil
elseif type(k) ~= 'string' or not options.backtranslate then
return k, v
else
local backtranslate = options.backtranslate[k]
if backtranslate == nil then
-- Skip this one. This is a tail call, so this won't cause stack overflow
return translatenext(invariant)
else
return backtranslate, v
end
end
end
metatable.__pairs = function ()
-- Called when pairs is run on the args table.
if not metatable.donePairs then
mergeArgs(argTables)
metatable.donePairs = true
end
return translatenext, { t = metaArgs }
end
local function inext(t, i)
-- This uses our __index metamethod
local v = t[i + 1]
if v ~= nil then
return i + 1, v
end
end
metatable.__ipairs = function (t)
-- Called when ipairs is run on the args table.
return inext, t, 0
end
return args
end
return arguments
3134ecce8429b810d445e29eae115e2ae4c36c53
Module:Arguments/doc
828
7
9
2023-12-27T04:46:31Z
CreepersNeedHugs
2
Created page with "{{documentation subpage}} This module provides easy processing of arguments passed from <code>#invoke</code>. It is a meta-module, meant for use by other modules, and should not be called from <code>#invoke</code> directly. Its features include: * Easy trimming of arguments and removal of blank arguments. * Arguments can be passed by both the current frame and by the parent frame at the same time. (More details below.) * Arguments can be passed in directly from another L..."
wikitext
text/x-wiki
{{documentation subpage}}
This module provides easy processing of arguments passed from <code>#invoke</code>. It is a meta-module, meant for use by other modules, and should not be called from <code>#invoke</code> directly. Its features include:
* Easy trimming of arguments and removal of blank arguments.
* Arguments can be passed by both the current frame and by the parent frame at the same time. (More details below.)
* Arguments can be passed in directly from another Lua module or from the debug console.
* Most features can be customized.
== Basic use ==
First, you need to load the module. It contains one function, named <code>getArgs</code>.
<syntaxhighlight lang="lua">
local getArgs = require('Module:Arguments').getArgs
</syntaxhighlight>
In the most basic scenario, you can use getArgs inside your main function. The variable <code>args</code> is a table containing the arguments from #invoke. (See below for details.)
<syntaxhighlight lang="lua">
local getArgs = require('Module:Arguments').getArgs
local p = {}
function p.main(frame)
local args = getArgs(frame)
-- Main module code goes here.
end
return p
</syntaxhighlight>
=== Recommended practice ===
However, the recommended practice is to use a function just for processing arguments from #invoke. This means that if someone calls your module from another Lua module you don't have to have a frame object available, which improves performance.
<syntaxhighlight lang="lua">
local getArgs = require('Module:Arguments').getArgs
local p = {}
function p.main(frame)
local args = getArgs(frame)
return p._main(args)
end
function p._main(args)
-- Main module code goes here.
end
return p
</syntaxhighlight>
The way this is called from a template is <code><nowiki>{{#invoke:Example|main}}</nowiki></code> (optionally with some parameters like <code><nowiki>{{#invoke:Example|main|arg1=value1|arg2=value2}}</nowiki></code>), and the way this is called from a module is <syntaxhighlight lang=lua inline>require('Module:Example')._main({arg1 = 'value1', arg2 = value2, 'spaced arg3' = 'value3'})</syntaxhighlight>. What this second one does is construct a table with the arguments in it, then gives that table to the p._main(args) function, which uses it natively.
=== Multiple functions ===
If you want multiple functions to use the arguments, and you also want them to be accessible from #invoke, you can use a wrapper function.
<syntaxhighlight lang="lua">
local getArgs = require('Module:Arguments').getArgs
local p = {}
local function makeInvokeFunc(funcName)
return function (frame)
local args = getArgs(frame)
return p[funcName](args)
end
end
p.func1 = makeInvokeFunc('_func1')
function p._func1(args)
-- Code for the first function goes here.
end
p.func2 = makeInvokeFunc('_func2')
function p._func2(args)
-- Code for the second function goes here.
end
return p
</syntaxhighlight>
=== Options ===
The following options are available. They are explained in the sections below.
<syntaxhighlight lang="lua">
local args = getArgs(frame, {
trim = false,
removeBlanks = false,
valueFunc = function (key, value)
-- Code for processing one argument
end,
frameOnly = true,
parentOnly = true,
parentFirst = true,
wrappers = {
'Template:A wrapper template',
'Template:Another wrapper template'
},
readOnly = true,
noOverwrite = true
})
</syntaxhighlight>
=== Trimming and removing blanks ===
Blank arguments often trip up coders new to converting MediaWiki templates to Lua. In template syntax, blank strings and strings consisting only of whitespace are considered false. However, in Lua, blank strings and strings consisting of whitespace are considered true. This means that if you don't pay attention to such arguments when you write your Lua modules, you might treat something as true that should actually be treated as false. To avoid this, by default this module removes all blank arguments.
Similarly, whitespace can cause problems when dealing with positional arguments. Although whitespace is trimmed for named arguments coming from #invoke, it is preserved for positional arguments. Most of the time this additional whitespace is not desired, so this module trims it off by default.
However, sometimes you want to use blank arguments as input, and sometimes you want to keep additional whitespace. This can be necessary to convert some templates exactly as they were written. If you want to do this, you can set the <code>trim</code> and <code>removeBlanks</code> arguments to <code>false</code>.
<syntaxhighlight lang="lua">
local args = getArgs(frame, {
trim = false,
removeBlanks = false
})
</syntaxhighlight>
=== Custom formatting of arguments ===
Sometimes you want to remove some blank arguments but not others, or perhaps you might want to put all of the positional arguments in lower case. To do things like this you can use the <code>valueFunc</code> option. The input to this option must be a function that takes two parameters, <code>key</code> and <code>value</code>, and returns a single value. This value is what you will get when you access the field <code>key</code> in the <code>args</code> table.
Example 1: this function preserves whitespace for the first positional argument, but trims all other arguments and removes all other blank arguments.
<syntaxhighlight lang="lua">
local args = getArgs(frame, {
valueFunc = function (key, value)
if key == 1 then
return value
elseif value then
value = mw.text.trim(value)
if value ~= '' then
return value
end
end
return nil
end
})
</syntaxhighlight>
Example 2: this function removes blank arguments and converts all arguments to lower case, but doesn't trim whitespace from positional parameters.
<syntaxhighlight lang="lua">
local args = getArgs(frame, {
valueFunc = function (key, value)
if not value then
return nil
end
value = mw.ustring.lower(value)
if mw.ustring.find(value, '%S') then
return value
end
return nil
end
})
</syntaxhighlight>
Note: the above functions will fail if passed input that is not of type <code>string</code> or <code>nil</code>. This might be the case if you use the <code>getArgs</code> function in the main function of your module, and that function is called by another Lua module. In this case, you will need to check the type of your input. This is not a problem if you are using a function specially for arguments from #invoke (i.e. you have <code>p.main</code> and <code>p._main</code> functions, or something similar).
Examples 1 and 2 with type checking:
Example 1:
<syntaxhighlight lang="lua">
local args = getArgs(frame, {
valueFunc = function (key, value)
if key == 1 then
return value
elseif type(value) == 'string' then
value = mw.text.trim(value)
if value ~= '' then
return value
else
return nil
end
else
return value
end
end
})
</syntaxhighlight>
Example 2:
<syntaxhighlight lang="lua">
local args = getArgs(frame, {
valueFunc = function (key, value)
if type(value) == 'string' then
value = mw.ustring.lower(value)
if mw.ustring.find(value, '%S') then
return value
else
return nil
end
else
return value
end
end
})
</syntaxhighlight>
Also, please note that the <code>valueFunc</code> function is called more or less every time an argument is requested from the <code>args</code> table, so if you care about performance you should make sure you aren't doing anything inefficient with your code.
=== Frames and parent frames ===
Arguments in the <code>args</code> table can be passed from the current frame or from its parent frame at the same time. To understand what this means, it is easiest to give an example. Let's say that we have a module called <code>Module:ExampleArgs</code>. This module prints the first two positional arguments that it is passed.
Module:ExampleArgs code:
<syntaxhighlight lang="lua">
local getArgs = require('Module:Arguments').getArgs
local p = {}
function p.main(frame)
local args = getArgs(frame)
return p._main(args)
end
function p._main(args)
local first = args[1] or ''
local second = args[2] or ''
return first .. ' ' .. second
end
return p
</syntaxhighlight>
<code>Module:ExampleArgs</code> is then called by <code>Template:ExampleArgs</code>, which contains the code <code><nowiki>{{#invoke:ExampleArgs|main|firstInvokeArg}}</nowiki></code>. This produces the result "firstInvokeArg".
Now if we were to call <code>Template:ExampleArgs</code>, the following would happen:
{| class="wikitable" style="width: 50em; max-width: 100%;"
|-
! style="width: 60%;" | Code
! style="width: 40%;" | Result
|-
| <code><nowiki>{{ExampleArgs}}</nowiki></code>
| firstInvokeArg
|-
| <code><nowiki>{{ExampleArgs|firstTemplateArg}}</nowiki></code>
| firstInvokeArg
|-
| <code><nowiki>{{ExampleArgs|firstTemplateArg|secondTemplateArg}}</nowiki></code>
| firstInvokeArg secondTemplateArg
|}
There are three options you can set to change this behaviour: <code>frameOnly</code>, <code>parentOnly</code> and <code>parentFirst</code>. If you set <code>frameOnly</code> then only arguments passed from the current frame will be accepted; if you set <code>parentOnly</code> then only arguments passed from the parent frame will be accepted; and if you set <code>parentFirst</code> then arguments will be passed from both the current and parent frames, but the parent frame will have priority over the current frame. Here are the results in terms of <code>Template:ExampleArgs</code>:
; frameOnly
{| class="wikitable" style="width: 50em; max-width: 100%;"
|-
! style="width: 60%;" | Code
! style="width: 40%;" | Result
|-
| <code><nowiki>{{ExampleArgs}}</nowiki></code>
| firstInvokeArg
|-
| <code><nowiki>{{ExampleArgs|firstTemplateArg}}</nowiki></code>
| firstInvokeArg
|-
| <code><nowiki>{{ExampleArgs|firstTemplateArg|secondTemplateArg}}</nowiki></code>
| firstInvokeArg
|}
; parentOnly
{| class="wikitable" style="width: 50em; max-width: 100%;"
|-
! style="width: 60%;" | Code
! style="width: 40%;" | Result
|-
| <code><nowiki>{{ExampleArgs}}</nowiki></code>
|
|-
| <code><nowiki>{{ExampleArgs|firstTemplateArg}}</nowiki></code>
| firstTemplateArg
|-
| <code><nowiki>{{ExampleArgs|firstTemplateArg|secondTemplateArg}}</nowiki></code>
| firstTemplateArg secondTemplateArg
|}
; parentFirst
{| class="wikitable" style="width: 50em; max-width: 100%;"
|-
! style="width: 60%;" | Code
! style="width: 40%;" | Result
|-
| <code><nowiki>{{ExampleArgs}}</nowiki></code>
| firstInvokeArg
|-
| <code><nowiki>{{ExampleArgs|firstTemplateArg}}</nowiki></code>
| firstTemplateArg
|-
| <code><nowiki>{{ExampleArgs|firstTemplateArg|secondTemplateArg}}</nowiki></code>
| firstTemplateArg secondTemplateArg
|}
Notes:
# If you set both the <code>frameOnly</code> and <code>parentOnly</code> options, the module won't fetch any arguments at all from #invoke. This is probably not what you want.
# In some situations a parent frame may not be available, e.g. if getArgs is passed the parent frame rather than the current frame. In this case, only the frame arguments will be used (unless parentOnly is set, in which case no arguments will be used) and the <code>parentFirst</code> and <code>frameOnly</code> options will have no effect.
=== Wrappers ===
The ''wrappers'' option is used to specify a limited number of templates as ''wrapper templates'', that is, templates whose only purpose is to call a module. If the module detects that it is being called from a wrapper template, it will only check for arguments in the parent frame; otherwise it will only check for arguments in the frame passed to getArgs. This allows modules to be called by either #invoke or through a wrapper template without the loss of performance associated with having to check both the frame and the parent frame for each argument lookup.
For example, the only content of [[w:Template:Side box]] (excluding content in <noinclude> tags) is <code><nowiki>{{#invoke:Side box|main}}</nowiki></code>. There is no point in checking the arguments passed directly to the #invoke statement for this template, as no arguments will ever be specified there. We can avoid checking arguments passed to #invoke by using the ''parentOnly'' option, but if we do this then #invoke will not work from other pages either. If this were the case, the <nowiki>|text=Some text</nowiki> in the code <code><nowiki>{{#invoke:Side box|main|text=Some text}}</nowiki></code> would be ignored completely, no matter what page it was used from. By using the <code>wrappers</code> option to specify 'Template:Side box' as a wrapper, we can make <code><nowiki>{{#invoke:Side box|main|text=Some text}}</nowiki></code> work from most pages, while still not requiring that the module check for arguments on the [[w:Template:Side box]] page itself.
Wrappers can be specified either as a string, or as an array of strings.
<syntaxhighlight lang="lua">
local args = getArgs(frame, {
wrappers = 'Template:Wrapper template'
})
</syntaxhighlight>
<syntaxhighlight lang="lua">
local args = getArgs(frame, {
wrappers = {
'Template:Wrapper 1',
'Template:Wrapper 2',
-- Any number of wrapper templates can be added here.
}
})
</syntaxhighlight>
Notes:
# The module will automatically detect if it is being called from a wrapper template's /sandbox subpage, so there is no need to specify sandbox pages explicitly.
# The ''wrappers'' option effectively changes the default of the ''frameOnly'' and ''parentOnly'' options. If, for example, ''parentOnly'' were explicitly set to 0 with ''wrappers'' set, calls via wrapper templates would result in both frame and parent arguments being loaded, though calls not via wrapper templates would result in only frame arguments being loaded.
# If the ''wrappers'' option is set and no parent frame is available, the module will always get the arguments from the frame passed to <code>getArgs</code>.
=== Writing to the args table ===
Sometimes it can be useful to write new values to the args table. This is possible with the default settings of this module. (However, bear in mind that it is usually better coding style to create a new table with your new values and copy arguments from the args table as needed.)
<syntaxhighlight lang="lua">
args.foo = 'some value'
</syntaxhighlight>
It is possible to alter this behaviour with the <code>readOnly</code> and <code>noOverwrite</code> options. If <code>readOnly</code> is set then it is not possible to write any values to the args table at all. If <code>noOverwrite</code> is set, then it is possible to add new values to the table, but it is not possible to add a value if it would overwrite any arguments that are passed from #invoke.
=== Ref tags ===
This module uses [[mw:Extension:Scribunto/Lua reference manual#Metatables|metatables]] to fetch arguments from #invoke. This allows access to both the frame arguments and the parent frame arguments without using the <code>pairs()</code> function. This can help if your module might be passed <ref> tags as input.
As soon as <ref> tags are accessed from Lua, they are processed by the MediaWiki software and the reference will appear in the reference list at the bottom of the article. If your module proceeds to omit the reference tag from the output, you will end up with a phantom reference – a reference that appears in the reference list but without any number linking to it. This has been a problem with modules that use <code>pairs()</code> to detect whether to use the arguments from the frame or the parent frame, as those modules automatically process every available argument.
This module solves this problem by allowing access to both frame and parent frame arguments, while still only fetching those arguments when it is necessary. The problem will still occur if you use <code>pairs(args)</code> elsewhere in your module, however.
=== Known limitations ===
The use of metatables also has its downsides. Most of the normal Lua table tools won't work properly on the args table, including the <code>#</code> operator, the <code>next()</code> function, and the functions in the table library. If using these is important for your module, you should use your own argument processing function instead of this module.
fe30c5ad9e29eae50816e55d20e5582b23b65e0a
10
9
2023-12-27T04:50:02Z
CreepersNeedHugs
2
wikitext
text/x-wiki
{{documentation subpage}}
: '''NOTICE: ''The Man in the High Castle'' Wiki's [[:Module:Arguments|Module:Arguments]] is partially or fully copied from [[w:c:dev:Miraheze Developer Wiki|Miraheze Developer Wiki]]'s [[:w:c:dev:Module:Arguments|Module:Arguments]].'''
: '''NOTICE: ''The Man in the High Castle'' Wiki's [[:Module:Arguments/doc|Module:Arguments/doc]] is partially or fully copied from [[w:c:dev:Miraheze Developer Wiki|Miraheze Developer Wiki]]'s [[:w:c:dev:Module:Arguments/doc|Module:Arguments/doc]].'''
This module provides easy processing of arguments passed from <code>#invoke</code>. It is a meta-module, meant for use by other modules, and should not be called from <code>#invoke</code> directly. Its features include:
* Easy trimming of arguments and removal of blank arguments.
* Arguments can be passed by both the current frame and by the parent frame at the same time. (More details below.)
* Arguments can be passed in directly from another Lua module or from the debug console.
* Most features can be customized.
== Basic use ==
First, you need to load the module. It contains one function, named <code>getArgs</code>.
<syntaxhighlight lang="lua">
local getArgs = require('Module:Arguments').getArgs
</syntaxhighlight>
In the most basic scenario, you can use getArgs inside your main function. The variable <code>args</code> is a table containing the arguments from #invoke. (See below for details.)
<syntaxhighlight lang="lua">
local getArgs = require('Module:Arguments').getArgs
local p = {}
function p.main(frame)
local args = getArgs(frame)
-- Main module code goes here.
end
return p
</syntaxhighlight>
=== Recommended practice ===
However, the recommended practice is to use a function just for processing arguments from #invoke. This means that if someone calls your module from another Lua module you don't have to have a frame object available, which improves performance.
<syntaxhighlight lang="lua">
local getArgs = require('Module:Arguments').getArgs
local p = {}
function p.main(frame)
local args = getArgs(frame)
return p._main(args)
end
function p._main(args)
-- Main module code goes here.
end
return p
</syntaxhighlight>
The way this is called from a template is <code><nowiki>{{#invoke:Example|main}}</nowiki></code> (optionally with some parameters like <code><nowiki>{{#invoke:Example|main|arg1=value1|arg2=value2}}</nowiki></code>), and the way this is called from a module is <syntaxhighlight lang=lua inline>require('Module:Example')._main({arg1 = 'value1', arg2 = value2, 'spaced arg3' = 'value3'})</syntaxhighlight>. What this second one does is construct a table with the arguments in it, then gives that table to the p._main(args) function, which uses it natively.
=== Multiple functions ===
If you want multiple functions to use the arguments, and you also want them to be accessible from #invoke, you can use a wrapper function.
<syntaxhighlight lang="lua">
local getArgs = require('Module:Arguments').getArgs
local p = {}
local function makeInvokeFunc(funcName)
return function (frame)
local args = getArgs(frame)
return p[funcName](args)
end
end
p.func1 = makeInvokeFunc('_func1')
function p._func1(args)
-- Code for the first function goes here.
end
p.func2 = makeInvokeFunc('_func2')
function p._func2(args)
-- Code for the second function goes here.
end
return p
</syntaxhighlight>
=== Options ===
The following options are available. They are explained in the sections below.
<syntaxhighlight lang="lua">
local args = getArgs(frame, {
trim = false,
removeBlanks = false,
valueFunc = function (key, value)
-- Code for processing one argument
end,
frameOnly = true,
parentOnly = true,
parentFirst = true,
wrappers = {
'Template:A wrapper template',
'Template:Another wrapper template'
},
readOnly = true,
noOverwrite = true
})
</syntaxhighlight>
=== Trimming and removing blanks ===
Blank arguments often trip up coders new to converting MediaWiki templates to Lua. In template syntax, blank strings and strings consisting only of whitespace are considered false. However, in Lua, blank strings and strings consisting of whitespace are considered true. This means that if you don't pay attention to such arguments when you write your Lua modules, you might treat something as true that should actually be treated as false. To avoid this, by default this module removes all blank arguments.
Similarly, whitespace can cause problems when dealing with positional arguments. Although whitespace is trimmed for named arguments coming from #invoke, it is preserved for positional arguments. Most of the time this additional whitespace is not desired, so this module trims it off by default.
However, sometimes you want to use blank arguments as input, and sometimes you want to keep additional whitespace. This can be necessary to convert some templates exactly as they were written. If you want to do this, you can set the <code>trim</code> and <code>removeBlanks</code> arguments to <code>false</code>.
<syntaxhighlight lang="lua">
local args = getArgs(frame, {
trim = false,
removeBlanks = false
})
</syntaxhighlight>
=== Custom formatting of arguments ===
Sometimes you want to remove some blank arguments but not others, or perhaps you might want to put all of the positional arguments in lower case. To do things like this you can use the <code>valueFunc</code> option. The input to this option must be a function that takes two parameters, <code>key</code> and <code>value</code>, and returns a single value. This value is what you will get when you access the field <code>key</code> in the <code>args</code> table.
Example 1: this function preserves whitespace for the first positional argument, but trims all other arguments and removes all other blank arguments.
<syntaxhighlight lang="lua">
local args = getArgs(frame, {
valueFunc = function (key, value)
if key == 1 then
return value
elseif value then
value = mw.text.trim(value)
if value ~= '' then
return value
end
end
return nil
end
})
</syntaxhighlight>
Example 2: this function removes blank arguments and converts all arguments to lower case, but doesn't trim whitespace from positional parameters.
<syntaxhighlight lang="lua">
local args = getArgs(frame, {
valueFunc = function (key, value)
if not value then
return nil
end
value = mw.ustring.lower(value)
if mw.ustring.find(value, '%S') then
return value
end
return nil
end
})
</syntaxhighlight>
Note: the above functions will fail if passed input that is not of type <code>string</code> or <code>nil</code>. This might be the case if you use the <code>getArgs</code> function in the main function of your module, and that function is called by another Lua module. In this case, you will need to check the type of your input. This is not a problem if you are using a function specially for arguments from #invoke (i.e. you have <code>p.main</code> and <code>p._main</code> functions, or something similar).
Examples 1 and 2 with type checking:
Example 1:
<syntaxhighlight lang="lua">
local args = getArgs(frame, {
valueFunc = function (key, value)
if key == 1 then
return value
elseif type(value) == 'string' then
value = mw.text.trim(value)
if value ~= '' then
return value
else
return nil
end
else
return value
end
end
})
</syntaxhighlight>
Example 2:
<syntaxhighlight lang="lua">
local args = getArgs(frame, {
valueFunc = function (key, value)
if type(value) == 'string' then
value = mw.ustring.lower(value)
if mw.ustring.find(value, '%S') then
return value
else
return nil
end
else
return value
end
end
})
</syntaxhighlight>
Also, please note that the <code>valueFunc</code> function is called more or less every time an argument is requested from the <code>args</code> table, so if you care about performance you should make sure you aren't doing anything inefficient with your code.
=== Frames and parent frames ===
Arguments in the <code>args</code> table can be passed from the current frame or from its parent frame at the same time. To understand what this means, it is easiest to give an example. Let's say that we have a module called <code>Module:ExampleArgs</code>. This module prints the first two positional arguments that it is passed.
Module:ExampleArgs code:
<syntaxhighlight lang="lua">
local getArgs = require('Module:Arguments').getArgs
local p = {}
function p.main(frame)
local args = getArgs(frame)
return p._main(args)
end
function p._main(args)
local first = args[1] or ''
local second = args[2] or ''
return first .. ' ' .. second
end
return p
</syntaxhighlight>
<code>Module:ExampleArgs</code> is then called by <code>Template:ExampleArgs</code>, which contains the code <code><nowiki>{{#invoke:ExampleArgs|main|firstInvokeArg}}</nowiki></code>. This produces the result "firstInvokeArg".
Now if we were to call <code>Template:ExampleArgs</code>, the following would happen:
{| class="wikitable" style="width: 50em; max-width: 100%;"
|-
! style="width: 60%;" | Code
! style="width: 40%;" | Result
|-
| <code><nowiki>{{ExampleArgs}}</nowiki></code>
| firstInvokeArg
|-
| <code><nowiki>{{ExampleArgs|firstTemplateArg}}</nowiki></code>
| firstInvokeArg
|-
| <code><nowiki>{{ExampleArgs|firstTemplateArg|secondTemplateArg}}</nowiki></code>
| firstInvokeArg secondTemplateArg
|}
There are three options you can set to change this behaviour: <code>frameOnly</code>, <code>parentOnly</code> and <code>parentFirst</code>. If you set <code>frameOnly</code> then only arguments passed from the current frame will be accepted; if you set <code>parentOnly</code> then only arguments passed from the parent frame will be accepted; and if you set <code>parentFirst</code> then arguments will be passed from both the current and parent frames, but the parent frame will have priority over the current frame. Here are the results in terms of <code>Template:ExampleArgs</code>:
; frameOnly
{| class="wikitable" style="width: 50em; max-width: 100%;"
|-
! style="width: 60%;" | Code
! style="width: 40%;" | Result
|-
| <code><nowiki>{{ExampleArgs}}</nowiki></code>
| firstInvokeArg
|-
| <code><nowiki>{{ExampleArgs|firstTemplateArg}}</nowiki></code>
| firstInvokeArg
|-
| <code><nowiki>{{ExampleArgs|firstTemplateArg|secondTemplateArg}}</nowiki></code>
| firstInvokeArg
|}
; parentOnly
{| class="wikitable" style="width: 50em; max-width: 100%;"
|-
! style="width: 60%;" | Code
! style="width: 40%;" | Result
|-
| <code><nowiki>{{ExampleArgs}}</nowiki></code>
|
|-
| <code><nowiki>{{ExampleArgs|firstTemplateArg}}</nowiki></code>
| firstTemplateArg
|-
| <code><nowiki>{{ExampleArgs|firstTemplateArg|secondTemplateArg}}</nowiki></code>
| firstTemplateArg secondTemplateArg
|}
; parentFirst
{| class="wikitable" style="width: 50em; max-width: 100%;"
|-
! style="width: 60%;" | Code
! style="width: 40%;" | Result
|-
| <code><nowiki>{{ExampleArgs}}</nowiki></code>
| firstInvokeArg
|-
| <code><nowiki>{{ExampleArgs|firstTemplateArg}}</nowiki></code>
| firstTemplateArg
|-
| <code><nowiki>{{ExampleArgs|firstTemplateArg|secondTemplateArg}}</nowiki></code>
| firstTemplateArg secondTemplateArg
|}
Notes:
# If you set both the <code>frameOnly</code> and <code>parentOnly</code> options, the module won't fetch any arguments at all from #invoke. This is probably not what you want.
# In some situations a parent frame may not be available, e.g. if getArgs is passed the parent frame rather than the current frame. In this case, only the frame arguments will be used (unless parentOnly is set, in which case no arguments will be used) and the <code>parentFirst</code> and <code>frameOnly</code> options will have no effect.
=== Wrappers ===
The ''wrappers'' option is used to specify a limited number of templates as ''wrapper templates'', that is, templates whose only purpose is to call a module. If the module detects that it is being called from a wrapper template, it will only check for arguments in the parent frame; otherwise it will only check for arguments in the frame passed to getArgs. This allows modules to be called by either #invoke or through a wrapper template without the loss of performance associated with having to check both the frame and the parent frame for each argument lookup.
For example, the only content of [[w:Template:Side box]] (excluding content in <noinclude> tags) is <code><nowiki>{{#invoke:Side box|main}}</nowiki></code>. There is no point in checking the arguments passed directly to the #invoke statement for this template, as no arguments will ever be specified there. We can avoid checking arguments passed to #invoke by using the ''parentOnly'' option, but if we do this then #invoke will not work from other pages either. If this were the case, the <nowiki>|text=Some text</nowiki> in the code <code><nowiki>{{#invoke:Side box|main|text=Some text}}</nowiki></code> would be ignored completely, no matter what page it was used from. By using the <code>wrappers</code> option to specify 'Template:Side box' as a wrapper, we can make <code><nowiki>{{#invoke:Side box|main|text=Some text}}</nowiki></code> work from most pages, while still not requiring that the module check for arguments on the [[w:Template:Side box]] page itself.
Wrappers can be specified either as a string, or as an array of strings.
<syntaxhighlight lang="lua">
local args = getArgs(frame, {
wrappers = 'Template:Wrapper template'
})
</syntaxhighlight>
<syntaxhighlight lang="lua">
local args = getArgs(frame, {
wrappers = {
'Template:Wrapper 1',
'Template:Wrapper 2',
-- Any number of wrapper templates can be added here.
}
})
</syntaxhighlight>
Notes:
# The module will automatically detect if it is being called from a wrapper template's /sandbox subpage, so there is no need to specify sandbox pages explicitly.
# The ''wrappers'' option effectively changes the default of the ''frameOnly'' and ''parentOnly'' options. If, for example, ''parentOnly'' were explicitly set to 0 with ''wrappers'' set, calls via wrapper templates would result in both frame and parent arguments being loaded, though calls not via wrapper templates would result in only frame arguments being loaded.
# If the ''wrappers'' option is set and no parent frame is available, the module will always get the arguments from the frame passed to <code>getArgs</code>.
=== Writing to the args table ===
Sometimes it can be useful to write new values to the args table. This is possible with the default settings of this module. (However, bear in mind that it is usually better coding style to create a new table with your new values and copy arguments from the args table as needed.)
<syntaxhighlight lang="lua">
args.foo = 'some value'
</syntaxhighlight>
It is possible to alter this behaviour with the <code>readOnly</code> and <code>noOverwrite</code> options. If <code>readOnly</code> is set then it is not possible to write any values to the args table at all. If <code>noOverwrite</code> is set, then it is possible to add new values to the table, but it is not possible to add a value if it would overwrite any arguments that are passed from #invoke.
=== Ref tags ===
This module uses [[mw:Extension:Scribunto/Lua reference manual#Metatables|metatables]] to fetch arguments from #invoke. This allows access to both the frame arguments and the parent frame arguments without using the <code>pairs()</code> function. This can help if your module might be passed <ref> tags as input.
As soon as <ref> tags are accessed from Lua, they are processed by the MediaWiki software and the reference will appear in the reference list at the bottom of the article. If your module proceeds to omit the reference tag from the output, you will end up with a phantom reference – a reference that appears in the reference list but without any number linking to it. This has been a problem with modules that use <code>pairs()</code> to detect whether to use the arguments from the frame or the parent frame, as those modules automatically process every available argument.
This module solves this problem by allowing access to both frame and parent frame arguments, while still only fetching those arguments when it is necessary. The problem will still occur if you use <code>pairs(args)</code> elsewhere in your module, however.
=== Known limitations ===
The use of metatables also has its downsides. Most of the normal Lua table tools won't work properly on the args table, including the <code>#</code> operator, the <code>next()</code> function, and the functions in the table library. If using these is important for your module, you should use your own argument processing function instead of this module.
6a697e99d5d79e0fb2d05c1da8c4f99a3e826fa8
Template:Documentation subpage
10
8
11
2023-12-27T04:50:47Z
CreepersNeedHugs
2
Created page with "<includeonly><!-- -->{{#ifeq:{{lc:{{SUBPAGENAME}}}} |{{{override|doc}}} | <!--(this template has been transcluded on a /doc or /{{{override}}} page)--> </includeonly><!-- -->{{#ifeq:{{{doc-notice|show}}} |show | {{Mbox | type = notice | style = margin-bottom:1.0em; | image = [[File:Edit-copy green.svg|40px|alt=|link=]] | text = '''This is a documentation subpage''' for '''{{{1|:{{SUBJECTSPACE}}:..."
wikitext
text/x-wiki
<includeonly><!--
-->{{#ifeq:{{lc:{{SUBPAGENAME}}}} |{{{override|doc}}}
| <!--(this template has been transcluded on a /doc or /{{{override}}} page)-->
</includeonly><!--
-->{{#ifeq:{{{doc-notice|show}}} |show
| {{Mbox
| type = notice
| style = margin-bottom:1.0em;
| image = [[File:Edit-copy green.svg|40px|alt=|link=]]
| text =
'''This is a documentation subpage''' for '''{{{1|[[:{{SUBJECTSPACE}}:{{BASEPAGENAME}}]]}}}'''.<br/> It contains usage information, [[mw:Help:Categories|categories]] and other content that is not part of the original {{#if:{{{text2|}}} |{{{text2}}} |{{#if:{{{text1|}}} |{{{text1}}} | page}}}}.
}}
}}<!--
-->{{DEFAULTSORT:{{{defaultsort|{{PAGENAME}}}}}}}<!--
-->{{#if:{{{inhibit|}}} |<!--(don't categorize)-->
| <includeonly><!--
-->{{#ifexist:{{NAMESPACE}}:{{BASEPAGENAME}}
| [[Category:{{#switch:{{SUBJECTSPACE}} |Template=Template |Module=Module |User=User |#default=Wikipedia}} documentation pages]]
| [[Category:Documentation subpages without corresponding pages]]
}}<!--
--></includeonly>
}}<!--
(completing initial #ifeq: at start of template:)
--><includeonly>
| <!--(this template has not been transcluded on a /doc or /{{{override}}} page)-->
}}<!--
--></includeonly><noinclude>{{Documentation}}</noinclude>
471e685c1c643a5c6272e20e49824fffebad0448
Module:Documentation/config
828
9
12
2023-12-27T04:51:42Z
CreepersNeedHugs
2
Created page with "---------------------------------------------------------------------------------------------------- -- -- Configuration for Module:Documentation -- -- Here you can set the values of the parameters and messages used in Module:Documentation to -- localise it to your wiki and your language. Unless specified otherwise, values given here -- should be string values. ---------------------------------------------------------------------------------..."
Scribunto
text/plain
----------------------------------------------------------------------------------------------------
--
-- Configuration for Module:Documentation
--
-- Here you can set the values of the parameters and messages used in Module:Documentation to
-- localise it to your wiki and your language. Unless specified otherwise, values given here
-- should be string values.
----------------------------------------------------------------------------------------------------
local cfg = {} -- Do not edit this line.
----------------------------------------------------------------------------------------------------
-- Start box configuration
----------------------------------------------------------------------------------------------------
-- cfg['documentation-icon-wikitext']
-- The wikitext for the icon shown at the top of the template.
cfg['documentation-icon-wikitext'] = '[[File:Test Template Info-Icon - Version (2).svg|50px|link=|alt=]]'
-- cfg['template-namespace-heading']
-- The heading shown in the template namespace.
cfg['template-namespace-heading'] = 'Template documentation'
-- cfg['module-namespace-heading']
-- The heading shown in the module namespace.
cfg['module-namespace-heading'] = 'Module documentation'
-- cfg['file-namespace-heading']
-- The heading shown in the file namespace.
cfg['file-namespace-heading'] = 'Summary'
-- cfg['other-namespaces-heading']
-- The heading shown in other namespaces.
cfg['other-namespaces-heading'] = 'Documentation'
-- cfg['view-link-display']
-- The text to display for "view" links.
cfg['view-link-display'] = 'view'
-- cfg['edit-link-display']
-- The text to display for "edit" links.
cfg['edit-link-display'] = 'edit'
-- cfg['history-link-display']
-- The text to display for "history" links.
cfg['history-link-display'] = 'history'
-- cfg['purge-link-display']
-- The text to display for "purge" links.
cfg['purge-link-display'] = 'purge'
-- cfg['create-link-display']
-- The text to display for "create" links.
cfg['create-link-display'] = 'create'
----------------------------------------------------------------------------------------------------
-- Link box (end box) configuration
----------------------------------------------------------------------------------------------------
-- cfg['transcluded-from-blurb']
-- Notice displayed when the docs are transcluded from another page. $1 is a wikilink to that page.
cfg['transcluded-from-blurb'] = 'The above [[w:Wikipedia:Template documentation|documentation]] is [[mw:Help:Transclusion|transcluded]] from $1.'
--[[
-- cfg['create-module-doc-blurb']
-- Notice displayed in the module namespace when the documentation subpage does not exist.
-- $1 is a link to create the documentation page with the preload cfg['module-preload'] and the
-- display cfg['create-link-display'].
--]]
cfg['create-module-doc-blurb'] = 'You might want to $1 a documentation page for this [[mw:Extension:Scribunto/Lua reference manual|Scribunto module]].'
----------------------------------------------------------------------------------------------------
-- Experiment blurb configuration
----------------------------------------------------------------------------------------------------
--[[
-- cfg['experiment-blurb-template']
-- cfg['experiment-blurb-module']
-- The experiment blurb is the text inviting editors to experiment in sandbox and test cases pages.
-- It is only shown in the template and module namespaces. With the default English settings, it
-- might look like this:
--
-- Editors can experiment in this template's sandbox (edit | diff) and testcases (edit) pages.
--
-- In this example, "sandbox", "edit", "diff", "testcases", and "edit" would all be links.
--
-- There are two versions, cfg['experiment-blurb-template'] and cfg['experiment-blurb-module'], depending
-- on what namespace we are in.
--
-- Parameters:
--
-- $1 is a link to the sandbox page. If the sandbox exists, it is in the following format:
--
-- cfg['sandbox-link-display'] (cfg['sandbox-edit-link-display'] | cfg['compare-link-display'])
--
-- If the sandbox doesn't exist, it is in the format:
--
-- cfg['sandbox-link-display'] (cfg['sandbox-create-link-display'] | cfg['mirror-link-display'])
--
-- The link for cfg['sandbox-create-link-display'] link preloads the page with cfg['template-sandbox-preload']
-- or cfg['module-sandbox-preload'], depending on the current namespace. The link for cfg['mirror-link-display']
-- loads a default edit summary of cfg['mirror-edit-summary'].
--
-- $2 is a link to the test cases page. If the test cases page exists, it is in the following format:
--
-- cfg['testcases-link-display'] (cfg['testcases-edit-link-display'] | cfg['testcases-run-link-display'])
--
-- If the test cases page doesn't exist, it is in the format:
--
-- cfg['testcases-link-display'] (cfg['testcases-create-link-display'])
--
-- If the test cases page doesn't exist, the link for cfg['testcases-create-link-display'] preloads the
-- page with cfg['template-testcases-preload'] or cfg['module-testcases-preload'], depending on the current
-- namespace.
--]]
cfg['experiment-blurb-template'] = "Editors can experiment in this template's $1 and $2 pages."
cfg['experiment-blurb-module'] = "Editors can experiment in this module's $1 and $2 pages."
----------------------------------------------------------------------------------------------------
-- Sandbox link configuration
----------------------------------------------------------------------------------------------------
-- cfg['sandbox-subpage']
-- The name of the template subpage typically used for sandboxes.
cfg['sandbox-subpage'] = 'sandbox'
-- cfg['template-sandbox-preload']
-- Preload file for template sandbox pages.
cfg['template-sandbox-preload'] = 'Template:Documentation/preload-sandbox'
-- cfg['module-sandbox-preload']
-- Preload file for Lua module sandbox pages.
cfg['module-sandbox-preload'] = 'Template:Documentation/preload-module-sandbox'
-- cfg['sandbox-link-display']
-- The text to display for "sandbox" links.
cfg['sandbox-link-display'] = 'sandbox'
-- cfg['sandbox-edit-link-display']
-- The text to display for sandbox "edit" links.
cfg['sandbox-edit-link-display'] = 'edit'
-- cfg['sandbox-create-link-display']
-- The text to display for sandbox "create" links.
cfg['sandbox-create-link-display'] = 'create'
-- cfg['compare-link-display']
-- The text to display for "compare" links.
cfg['compare-link-display'] = 'diff'
-- cfg['mirror-edit-summary']
-- The default edit summary to use when a user clicks the "mirror" link. $1 is a wikilink to the
-- template page.
cfg['mirror-edit-summary'] = 'Create sandbox version of $1'
-- cfg['mirror-link-display']
-- The text to display for "mirror" links.
cfg['mirror-link-display'] = 'mirror'
-- cfg['mirror-link-preload']
-- The page to preload when a user clicks the "mirror" link.
cfg['mirror-link-preload'] = 'Template:Documentation/mirror'
----------------------------------------------------------------------------------------------------
-- Test cases link configuration
----------------------------------------------------------------------------------------------------
-- cfg['testcases-subpage']
-- The name of the template subpage typically used for test cases.
cfg['testcases-subpage'] = 'testcases'
-- cfg['template-testcases-preload']
-- Preload file for template test cases pages.
cfg['template-testcases-preload'] = 'Template:Documentation/preload-testcases'
-- cfg['module-testcases-preload']
-- Preload file for Lua module test cases pages.
cfg['module-testcases-preload'] = 'Template:Documentation/preload-module-testcases'
-- cfg['testcases-link-display']
-- The text to display for "testcases" links.
cfg['testcases-link-display'] = 'testcases'
-- cfg['testcases-edit-link-display']
-- The text to display for test cases "edit" links.
cfg['testcases-edit-link-display'] = 'edit'
-- cfg['testcases-run-link-display']
-- The text to display for test cases "run" links.
cfg['testcases-run-link-display'] = 'run'
-- cfg['testcases-create-link-display']
-- The text to display for test cases "create" links.
cfg['testcases-create-link-display'] = 'create'
----------------------------------------------------------------------------------------------------
-- Add categories blurb configuration
----------------------------------------------------------------------------------------------------
--[[
-- cfg['add-categories-blurb']
-- Text to direct users to add categories to the /doc subpage. Not used if the "content" or
-- "docname fed" arguments are set, as then it is not clear where to add the categories. $1 is a
-- link to the /doc subpage with a display value of cfg['doc-link-display'].
--]]
cfg['add-categories-blurb'] = 'Add categories to the $1 subpage.'
-- cfg['doc-link-display']
-- The text to display when linking to the /doc subpage.
cfg['doc-link-display'] = '/doc'
----------------------------------------------------------------------------------------------------
-- Subpages link configuration
----------------------------------------------------------------------------------------------------
--[[
-- cfg['subpages-blurb']
-- The "Subpages of this template" blurb. $1 is a link to the main template's subpages with a
-- display value of cfg['subpages-link-display']. In the English version this blurb is simply
-- the link followed by a period, and the link display provides the actual text.
--]]
cfg['subpages-blurb'] = '$1.'
--[[
-- cfg['subpages-link-display']
-- The text to display for the "subpages of this page" link. $1 is cfg['template-pagetype'],
-- cfg['module-pagetype'] or cfg['default-pagetype'], depending on whether the current page is in
-- the template namespace, the module namespace, or another namespace.
--]]
cfg['subpages-link-display'] = 'Subpages of this $1'
-- cfg['template-pagetype']
-- The pagetype to display for template pages.
cfg['template-pagetype'] = 'template'
-- cfg['module-pagetype']
-- The pagetype to display for Lua module pages.
cfg['module-pagetype'] = 'module'
-- cfg['default-pagetype']
-- The pagetype to display for pages other than templates or Lua modules.
cfg['default-pagetype'] = 'page'
----------------------------------------------------------------------------------------------------
-- Doc link configuration
----------------------------------------------------------------------------------------------------
-- cfg['doc-subpage']
-- The name of the subpage typically used for documentation pages.
cfg['doc-subpage'] = 'doc'
-- cfg['docpage-preload']
-- Preload file for template documentation pages in all namespaces.
cfg['docpage-preload'] = 'Template:Documentation/preload'
-- cfg['module-preload']
-- Preload file for Lua module documentation pages.
cfg['module-preload'] = 'Template:Documentation/preload-module-doc'
----------------------------------------------------------------------------------------------------
-- HTML and CSS configuration
----------------------------------------------------------------------------------------------------
-- cfg['templatestyles']
-- The name of the TemplateStyles page where CSS is kept.
-- Sandbox CSS will be at Module:Documentation/sandbox/styles.css when needed.
cfg['templatestyles'] = 'Module:Documentation/styles.css'
-- cfg['container']
-- Class which can be used to set flex or grid CSS on the
-- two child divs documentation and documentation-metadata
cfg['container'] = 'documentation-container'
-- cfg['main-div-classes']
-- Classes added to the main HTML "div" tag.
cfg['main-div-classes'] = 'documentation'
-- cfg['main-div-heading-class']
-- Class for the main heading for templates and modules and assoc. talk spaces
cfg['main-div-heading-class'] = 'documentation-heading'
-- cfg['start-box-class']
-- Class for the start box
cfg['start-box-class'] = 'documentation-startbox'
-- cfg['start-box-link-classes']
-- Classes used for the [view][edit][history] or [create] links in the start box.
-- mw-editsection-like is per [[Wikipedia:Village pump (technical)/Archive 117]]
cfg['start-box-link-classes'] = 'mw-editsection-like plainlinks'
-- cfg['end-box-class']
-- Class for the end box.
cfg['end-box-class'] = 'documentation-metadata'
-- cfg['end-box-plainlinks']
-- Plainlinks
cfg['end-box-plainlinks'] = 'plainlinks'
-- cfg['toolbar-class']
-- Class added for toolbar links.
cfg['toolbar-class'] = 'documentation-toolbar'
-- cfg['clear']
-- Just used to clear things.
cfg['clear'] = 'documentation-clear'
----------------------------------------------------------------------------------------------------
-- Tracking category configuration
----------------------------------------------------------------------------------------------------
-- cfg['display-strange-usage-category']
-- Set to true to enable output of cfg['strange-usage-category'] if the module is used on a /doc subpage
-- or a /testcases subpage. This should be a boolean value (either true or false).
cfg['display-strange-usage-category'] = true
-- cfg['strange-usage-category']
-- Category to output if cfg['display-strange-usage-category'] is set to true and the module is used on a
-- /doc subpage or a /testcases subpage.
cfg['strange-usage-category'] = 'Wikipedia pages with strange ((documentation)) usage'
--[[
----------------------------------------------------------------------------------------------------
-- End configuration
--
-- Don't edit anything below this line.
----------------------------------------------------------------------------------------------------
--]]
return cfg
d70e8b1402a2bbe08a1fef4b75d743e661af0c95
Module:Documentation/config/doc
828
10
13
2023-12-27T04:54:13Z
CreepersNeedHugs
2
Created page with "{{documentation subpage}} : '''NOTICE: ''The Man in the High Castle'' Wiki's [[:Module:Documentation/config|Module:Documentation/config]] is partially or fully copied from [[w:c:dev:Miraheze Developer Wiki]]'s [[:w:c:dev:Module:Documentation/config|Module:Documentation/config]].''' : '''NOTICE: ''The Man in the High Castle'' Wiki's [[:Module:Documentation/config/doc|Module:Documentation/config/doc]] is partially or fully copied from [[w:c:dev:Miraheze Developer Wiki]]'s..."
wikitext
text/x-wiki
{{documentation subpage}}
: '''NOTICE: ''The Man in the High Castle'' Wiki's [[:Module:Documentation/config|Module:Documentation/config]] is partially or fully copied from [[w:c:dev:Miraheze Developer Wiki]]'s [[:w:c:dev:Module:Documentation/config|Module:Documentation/config]].'''
: '''NOTICE: ''The Man in the High Castle'' Wiki's [[:Module:Documentation/config/doc|Module:Documentation/config/doc]] is partially or fully copied from [[w:c:dev:Miraheze Developer Wiki]]'s [[:w:c:dev:Module:Documentation/config/doc|Module:Documentation/config/doc]].'''
This is the configuration file for [[Module:Documentation]]. This file can be edited to allow easy translation/porting of the module to other wikis.
2dc1f1b99a7f7c9c4468c2e576ce40dbc35dd135
14
13
2023-12-27T04:54:44Z
CreepersNeedHugs
2
wikitext
text/x-wiki
{{documentation subpage}}
: '''NOTICE: ''The Man in the High Castle'' Wiki's [[:Module:Documentation/config|Module:Documentation/config]] is partially or fully copied from [[w:c:dev:Miraheze Developer Wiki|Miraheze Developer Wiki]]'s [[:w:c:dev:Module:Documentation/config|Module:Documentation/config]].'''
: '''NOTICE: ''The Man in the High Castle'' Wiki's [[:Module:Documentation/config/doc|Module:Documentation/config/doc]] is partially or fully copied from [[w:c:dev:Miraheze Developer Wiki|Miraheze Developer Wiki]]'s [[:w:c:dev:Module:Documentation/config/doc|Module:Documentation/config/doc]].'''
This is the configuration file for [[Module:Documentation]]. This file can be edited to allow easy translation/porting of the module to other wikis.
32736176c721e18e73590b6fdd458e961113224d
15
14
2023-12-27T04:56:50Z
CreepersNeedHugs
2
wikitext
text/x-wiki
{{documentation subpage}}
: '''NOTICE: ''The Man in the High Castle'' Wiki's [[:Module:Documentation/config|Module:Documentation/config]] is partially or fully copied from [[dev:Miraheze Developer Wiki|Miraheze Developer Wiki]]'s [[dev:Module:Documentation/config|Module:Documentation/config]].'''
: '''NOTICE: ''The Man in the High Castle'' Wiki's [[:Module:Documentation/config/doc|Module:Documentation/config/doc]] is partially or fully copied from [[dev:Miraheze Developer Wiki|Miraheze Developer Wiki]]'s [[dev:Module:Documentation/config/doc|Module:Documentation/config/doc]].'''
This is the configuration file for [[Module:Documentation]]. This file can be edited to allow easy translation/porting of the module to other wikis.
fc93a1a47f6129aaee798c7878a7cc05c3033611
Template:Mbox
10
11
16
2023-12-27T04:58:59Z
CreepersNeedHugs
2
Created page with "{{#invoke:Message box|mbox}}<noinclude> {{documentation}} <!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --> </noinclude>"
wikitext
text/x-wiki
{{#invoke:Message box|mbox}}<noinclude>
{{documentation}}
<!-- Categories go on the /doc subpage, and interwikis go on Wikidata. -->
</noinclude>
c262e205f85f774a23f74119179ceea11751d68e
Module:Message box
828
12
17
2023-12-27T05:00:22Z
CreepersNeedHugs
2
Created page with "-- This is a meta-module for producing message box templates, including -- {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}. -- Load necessary modules. require('Module:No globals') local getArgs local yesno = require('Module:Yesno') local templatestyles = 'Module:Message box/styles.css' -- Get a language object for formatDate and ucfirst. local lang = mw.language.getContentLanguage() -- Define constants local CONFIG_MODULE = 'Module:Messag..."
Scribunto
text/plain
-- This is a meta-module for producing message box templates, including
-- {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}.
-- Load necessary modules.
require('Module:No globals')
local getArgs
local yesno = require('Module:Yesno')
local templatestyles = 'Module:Message box/styles.css'
-- Get a language object for formatDate and ucfirst.
local lang = mw.language.getContentLanguage()
-- Define constants
local CONFIG_MODULE = 'Module:Message box/configuration'
local DEMOSPACES = {user = 'tmbox', talk = 'tmbox', image = 'imbox', file = 'imbox', category = 'cmbox', article = 'ambox', main = 'ambox'}
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function getTitleObject(...)
-- Get the title object, passing the function through pcall
-- in case we are over the expensive function count limit.
local success, title = pcall(mw.title.new, ...)
if success then
return title
end
end
local function union(t1, t2)
-- Returns the union of two arrays.
local vals = {}
for i, v in ipairs(t1) do
vals[v] = true
end
for i, v in ipairs(t2) do
vals[v] = true
end
local ret = {}
for k in pairs(vals) do
table.insert(ret, k)
end
table.sort(ret)
return ret
end
local function getArgNums(args, prefix)
local nums = {}
for k, v in pairs(args) do
local num = mw.ustring.match(tostring(k), '^' .. prefix .. '([1-9]%d*)$')
if num then
table.insert(nums, tonumber(num))
end
end
table.sort(nums)
return nums
end
--------------------------------------------------------------------------------
-- Box class definition
--------------------------------------------------------------------------------
local MessageBox = {}
MessageBox.__index = MessageBox
function MessageBox.new(boxType, args, cfg)
args = args or {}
local obj = {}
-- Set the title object and the namespace.
obj.title = getTitleObject(args.page) or mw.title.getCurrentTitle()
-- Set the config for our box type.
obj.cfg = cfg[boxType]
if not obj.cfg then
local ns = obj.title.namespace
-- boxType is "mbox" or invalid input
if args.demospace and args.demospace ~= '' then
-- implement demospace parameter of mbox
local demospace = string.lower(args.demospace)
if DEMOSPACES[demospace] then
-- use template from DEMOSPACES
obj.cfg = cfg[DEMOSPACES[demospace]]
elseif string.find( demospace, 'talk' ) then
-- demo as a talk page
obj.cfg = cfg.tmbox
else
-- default to ombox
obj.cfg = cfg.ombox
end
elseif ns == 0 then
obj.cfg = cfg.ambox -- main namespace
elseif ns == 6 then
obj.cfg = cfg.imbox -- file namespace
elseif ns == 14 then
obj.cfg = cfg.cmbox -- category namespace
else
local nsTable = mw.site.namespaces[ns]
if nsTable and nsTable.isTalk then
obj.cfg = cfg.tmbox -- any talk namespace
else
obj.cfg = cfg.ombox -- other namespaces or invalid input
end
end
end
-- Set the arguments, and remove all blank arguments except for the ones
-- listed in cfg.allowBlankParams.
do
local newArgs = {}
for k, v in pairs(args) do
if v ~= '' then
newArgs[k] = v
end
end
for i, param in ipairs(obj.cfg.allowBlankParams or {}) do
newArgs[param] = args[param]
end
obj.args = newArgs
end
-- Define internal data structure.
obj.categories = {}
obj.classes = {}
-- For lazy loading of [[Module:Category handler]].
obj.hasCategories = false
return setmetatable(obj, MessageBox)
end
function MessageBox:addCat(ns, cat, sort)
if not cat then
return nil
end
if sort then
cat = string.format('[[Category:%s|%s]]', cat, sort)
else
cat = string.format('[[Category:%s]]', cat)
end
self.hasCategories = true
self.categories[ns] = self.categories[ns] or {}
table.insert(self.categories[ns], cat)
end
function MessageBox:addClass(class)
if not class then
return nil
end
table.insert(self.classes, class)
end
function MessageBox:setParameters()
local args = self.args
local cfg = self.cfg
-- Get type data.
self.type = args.type
local typeData = cfg.types[self.type]
self.invalidTypeError = cfg.showInvalidTypeError
and self.type
and not typeData
typeData = typeData or cfg.types[cfg.default]
self.typeClass = typeData.class
self.typeImage = typeData.image
-- Find whether we are using a small message box.
self.isSmall = cfg.allowSmall and (
cfg.smallParam and args.small == cfg.smallParam
or not cfg.smallParam and yesno(args.small)
)
-- Add attributes, classes and styles.
self.id = args.id
self.name = args.name
if self.name then
self:addClass('box-' .. string.gsub(self.name,' ','_'))
end
if yesno(args.plainlinks) ~= false then
self:addClass('plainlinks')
end
for _, class in ipairs(cfg.classes or {}) do
self:addClass(class)
end
if self.isSmall then
self:addClass(cfg.smallClass or 'mbox-small')
end
self:addClass(self.typeClass)
self:addClass(args.class)
self.style = args.style
self.attrs = args.attrs
-- Set text style.
self.textstyle = args.textstyle
-- Find if we are on the template page or not. This functionality is only
-- used if useCollapsibleTextFields is set, or if both cfg.templateCategory
-- and cfg.templateCategoryRequireName are set.
self.useCollapsibleTextFields = cfg.useCollapsibleTextFields
if self.useCollapsibleTextFields
or cfg.templateCategory
and cfg.templateCategoryRequireName
then
if self.name then
local templateName = mw.ustring.match(
self.name,
'^[tT][eE][mM][pP][lL][aA][tT][eE][%s_]*:[%s_]*(.*)$'
) or self.name
templateName = 'Template:' .. templateName
self.templateTitle = getTitleObject(templateName)
end
self.isTemplatePage = self.templateTitle
and mw.title.equals(self.title, self.templateTitle)
end
-- Process data for collapsible text fields. At the moment these are only
-- used in {{ambox}}.
if self.useCollapsibleTextFields then
-- Get the self.issue value.
if self.isSmall and args.smalltext then
self.issue = args.smalltext
else
local sect
if args.sect == '' then
sect = 'This ' .. (cfg.sectionDefault or 'page')
elseif type(args.sect) == 'string' then
sect = 'This ' .. args.sect
end
local issue = args.issue
issue = type(issue) == 'string' and issue ~= '' and issue or nil
local text = args.text
text = type(text) == 'string' and text or nil
local issues = {}
table.insert(issues, sect)
table.insert(issues, issue)
table.insert(issues, text)
self.issue = table.concat(issues, ' ')
end
-- Get the self.talk value.
local talk = args.talk
-- Show talk links on the template page or template subpages if the talk
-- parameter is blank.
if talk == ''
and self.templateTitle
and (
mw.title.equals(self.templateTitle, self.title)
or self.title:isSubpageOf(self.templateTitle)
)
then
talk = '#'
elseif talk == '' then
talk = nil
end
if talk then
-- If the talk value is a talk page, make a link to that page. Else
-- assume that it's a section heading, and make a link to the talk
-- page of the current page with that section heading.
local talkTitle = getTitleObject(talk)
local talkArgIsTalkPage = true
if not talkTitle or not talkTitle.isTalkPage then
talkArgIsTalkPage = false
talkTitle = getTitleObject(
self.title.text,
mw.site.namespaces[self.title.namespace].talk.id
)
end
if talkTitle and talkTitle.exists then
local talkText = 'Relevant discussion may be found on'
if talkArgIsTalkPage then
talkText = string.format(
'%s [[%s|%s]].',
talkText,
talk,
talkTitle.prefixedText
)
else
talkText = string.format(
'%s the [[%s#%s|talk page]].',
talkText,
talkTitle.prefixedText,
talk
)
end
self.talk = talkText
end
end
-- Get other values.
self.fix = args.fix ~= '' and args.fix or nil
local date
if args.date and args.date ~= '' then
date = args.date
elseif args.date == '' and self.isTemplatePage then
date = lang:formatDate('F Y')
end
if date then
self.date = string.format(" <small class='date-container'>''(<span class='date'>%s</span>)''</small>", date)
end
self.info = args.info
end
-- Set the non-collapsible text field. At the moment this is used by all box
-- types other than ambox, and also by ambox when small=yes.
if self.isSmall then
self.text = args.smalltext or args.text
else
self.text = args.text
end
-- Set the below row.
self.below = cfg.below and args.below
-- General image settings.
self.imageCellDiv = not self.isSmall and cfg.imageCellDiv
self.imageEmptyCell = cfg.imageEmptyCell
if cfg.imageEmptyCellStyle then
self.imageEmptyCellStyle = 'border:none;padding:0px;width:1px'
end
-- Left image settings.
local imageLeft = self.isSmall and args.smallimage or args.image
if cfg.imageCheckBlank and imageLeft ~= 'blank' and imageLeft ~= 'none'
or not cfg.imageCheckBlank and imageLeft ~= 'none'
then
self.imageLeft = imageLeft
if not imageLeft then
local imageSize = self.isSmall
and (cfg.imageSmallSize or '30x30px')
or '40x40px'
self.imageLeft = string.format('[[File:%s|%s|link=|alt=]]', self.typeImage
or 'Imbox notice.png', imageSize)
end
end
-- Right image settings.
local imageRight = self.isSmall and args.smallimageright or args.imageright
if not (cfg.imageRightNone and imageRight == 'none') then
self.imageRight = imageRight
end
end
function MessageBox:setMainspaceCategories()
local args = self.args
local cfg = self.cfg
if not cfg.allowMainspaceCategories then
return nil
end
local nums = {}
for _, prefix in ipairs{'cat', 'category', 'all'} do
args[prefix .. '1'] = args[prefix]
nums = union(nums, getArgNums(args, prefix))
end
-- The following is roughly equivalent to the old {{Ambox/category}}.
local date = args.date
date = type(date) == 'string' and date
local preposition = 'from'
for _, num in ipairs(nums) do
local mainCat = args['cat' .. tostring(num)]
or args['category' .. tostring(num)]
local allCat = args['all' .. tostring(num)]
mainCat = type(mainCat) == 'string' and mainCat
allCat = type(allCat) == 'string' and allCat
if mainCat and date and date ~= '' then
local catTitle = string.format('%s %s %s', mainCat, preposition, date)
self:addCat(0, catTitle)
catTitle = getTitleObject('Category:' .. catTitle)
if not catTitle or not catTitle.exists then
self:addCat(0, 'Articles with invalid date parameter in template')
end
elseif mainCat and (not date or date == '') then
self:addCat(0, mainCat)
end
if allCat then
self:addCat(0, allCat)
end
end
end
function MessageBox:setTemplateCategories()
local args = self.args
local cfg = self.cfg
-- Add template categories.
if cfg.templateCategory then
if cfg.templateCategoryRequireName then
if self.isTemplatePage then
self:addCat(10, cfg.templateCategory)
end
elseif not self.title.isSubpage then
self:addCat(10, cfg.templateCategory)
end
end
-- Add template error categories.
if cfg.templateErrorCategory then
local templateErrorCategory = cfg.templateErrorCategory
local templateCat, templateSort
if not self.name and not self.title.isSubpage then
templateCat = templateErrorCategory
elseif self.isTemplatePage then
local paramsToCheck = cfg.templateErrorParamsToCheck or {}
local count = 0
for i, param in ipairs(paramsToCheck) do
if not args[param] then
count = count + 1
end
end
if count > 0 then
templateCat = templateErrorCategory
templateSort = tostring(count)
end
if self.categoryNums and #self.categoryNums > 0 then
templateCat = templateErrorCategory
templateSort = 'C'
end
end
self:addCat(10, templateCat, templateSort)
end
end
function MessageBox:setAllNamespaceCategories()
-- Set categories for all namespaces.
if self.invalidTypeError then
local allSort = (self.title.namespace == 0 and 'Main:' or '') .. self.title.prefixedText
self:addCat('all', 'Wikipedia message box parameter needs fixing', allSort)
end
end
function MessageBox:setCategories()
if self.title.namespace == 0 then
self:setMainspaceCategories()
elseif self.title.namespace == 10 then
self:setTemplateCategories()
end
self:setAllNamespaceCategories()
end
function MessageBox:renderCategories()
if not self.hasCategories then
-- No categories added, no need to pass them to Category handler so,
-- if it was invoked, it would return the empty string.
-- So we shortcut and return the empty string.
return ""
end
-- Convert category tables to strings and pass them through
-- [[Module:Category handler]].
return require('Module:Category handler')._main{
main = table.concat(self.categories[0] or {}),
template = table.concat(self.categories[10] or {}),
all = table.concat(self.categories.all or {}),
nocat = self.args.nocat,
page = self.args.page
}
end
function MessageBox:export()
local root = mw.html.create()
-- Create the box table.
local boxTable = root:tag('table')
boxTable:attr('id', self.id or nil)
for i, class in ipairs(self.classes or {}) do
boxTable:addClass(class or nil)
end
boxTable
:cssText(self.style or nil)
:attr('role', 'presentation')
if self.attrs then
boxTable:attr(self.attrs)
end
-- Add the left-hand image.
local row = boxTable:tag('tr')
if self.imageLeft then
local imageLeftCell = row:tag('td'):addClass('mbox-image')
if self.imageCellDiv then
-- If we are using a div, redefine imageLeftCell so that the image
-- is inside it. Divs use style="width: 52px;", which limits the
-- image width to 52px. If any images in a div are wider than that,
-- they may overlap with the text or cause other display problems.
imageLeftCell = imageLeftCell:tag('div'):css('width', '52px')
end
imageLeftCell:wikitext(self.imageLeft or nil)
elseif self.imageEmptyCell then
-- Some message boxes define an empty cell if no image is specified, and
-- some don't. The old template code in templates where empty cells are
-- specified gives the following hint: "No image. Cell with some width
-- or padding necessary for text cell to have 100% width."
row:tag('td')
:addClass('mbox-empty-cell')
:cssText(self.imageEmptyCellStyle or nil)
end
-- Add the text.
local textCell = row:tag('td'):addClass('mbox-text')
if self.useCollapsibleTextFields then
-- The message box uses advanced text parameters that allow things to be
-- collapsible. At the moment, only ambox uses this.
textCell:cssText(self.textstyle or nil)
local textCellDiv = textCell:tag('div')
textCellDiv
:addClass('mbox-text-span')
:wikitext(self.issue or nil)
if (self.talk or self.fix) and not self.isSmall then
textCellDiv:tag('span')
:addClass('hide-when-compact')
:wikitext(self.talk and (' ' .. self.talk) or nil)
:wikitext(self.fix and (' ' .. self.fix) or nil)
end
textCellDiv:wikitext(self.date and (' ' .. self.date) or nil)
if self.info and not self.isSmall then
textCellDiv
:tag('span')
:addClass('hide-when-compact')
:wikitext(self.info and (' ' .. self.info) or nil)
end
else
-- Default text formatting - anything goes.
textCell
:cssText(self.textstyle or nil)
:wikitext(self.text or nil)
end
-- Add the right-hand image.
if self.imageRight then
local imageRightCell = row:tag('td'):addClass('mbox-imageright')
if self.imageCellDiv then
-- If we are using a div, redefine imageRightCell so that the image
-- is inside it.
imageRightCell = imageRightCell:tag('div'):css('width', '52px')
end
imageRightCell
:wikitext(self.imageRight or nil)
end
-- Add the below row.
if self.below then
boxTable:tag('tr')
:tag('td')
:attr('colspan', self.imageRight and '3' or '2')
:addClass('mbox-text')
:cssText(self.textstyle or nil)
:wikitext(self.below or nil)
end
-- Add error message for invalid type parameters.
if self.invalidTypeError then
root:tag('div')
:css('text-align', 'center')
:wikitext(string.format(
'This message box is using an invalid "type=%s" parameter and needs fixing.',
self.type or ''
))
end
-- Add categories.
root:wikitext(self:renderCategories() or nil)
return tostring(root)
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p, mt = {}, {}
function p._exportClasses()
-- For testing.
return {
MessageBox = MessageBox
}
end
function p.main(boxType, args, cfgTables)
local box = MessageBox.new(boxType, args, cfgTables or mw.loadData(CONFIG_MODULE))
box:setParameters()
box:setCategories()
return box:export()
end
local function templatestyles(frame, src)
return mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = templatestyles} }
.. 'CONFIG_MODULE'
end
function mt.__index(t, k)
return function (frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return t.main(k, getArgs(frame, {trim = false, removeBlanks = false}))
end
end
return setmetatable(p, mt)
be00cd389f9f2afcd361e5d5e33622839555cbd9
Module:No globals
828
13
18
2023-12-27T05:01:51Z
CreepersNeedHugs
2
Created page with "local mt = getmetatable(_G) or {} function mt.__index (t, k) if k ~= 'arg' then error('Tried to read nil global ' .. tostring(k), 2) end return nil end function mt.__newindex(t, k, v) if k ~= 'arg' then error('Tried to write global ' .. tostring(k), 2) end rawset(t, k, v) end setmetatable(_G, mt)"
Scribunto
text/plain
local mt = getmetatable(_G) or {}
function mt.__index (t, k)
if k ~= 'arg' then
error('Tried to read nil global ' .. tostring(k), 2)
end
return nil
end
function mt.__newindex(t, k, v)
if k ~= 'arg' then
error('Tried to write global ' .. tostring(k), 2)
end
rawset(t, k, v)
end
setmetatable(_G, mt)
8ce3969f7d53b08bd00dabe4cc9780bc6afd412a
Module:Yesno
828
14
19
2023-12-27T05:02:55Z
CreepersNeedHugs
2
Created page with "-- Function allowing for consistent treatment of boolean-like wikitext input. -- It works similarly to the template {{yesno}}. return function (val, default) -- If your wiki uses non-ascii characters for any of "yes", "no", etc., you -- should replace "val:lower()" with "mw.ustring.lower(val)" in the -- following line. val = type(val) == 'string' and val:lower() or val if val == nil then return nil elseif val == true or val == 'yes' or val == 'y' or val =..."
Scribunto
text/plain
-- Function allowing for consistent treatment of boolean-like wikitext input.
-- It works similarly to the template {{yesno}}.
return function (val, default)
-- If your wiki uses non-ascii characters for any of "yes", "no", etc., you
-- should replace "val:lower()" with "mw.ustring.lower(val)" in the
-- following line.
val = type(val) == 'string' and val:lower() or val
if val == nil then
return nil
elseif val == true
or val == 'yes'
or val == 'y'
or val == 'true'
or val == 't'
or val == 'on'
or tonumber(val) == 1
then
return true
elseif val == false
or val == 'no'
or val == 'n'
or val == 'false'
or val == 'f'
or val == 'off'
or tonumber(val) == 0
then
return false
else
return default
end
end
f767643e7d12126d020d88d662a3dd057817b9dc
Module:Message box/configuration
828
15
20
2023-12-27T05:05:27Z
CreepersNeedHugs
2
Created page with "-------------------------------------------------------------------------------- -- Message box configuration -- -- -- -- This module contains configuration data for [[Module:Message box]]. -- -------------------------------------------------------------------------------- return { ambox = { types = { speedy = { class = 'ambox-spee..."
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Message box configuration --
-- --
-- This module contains configuration data for [[Module:Message box]]. --
--------------------------------------------------------------------------------
return {
ambox = {
types = {
speedy = {
class = 'ambox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'ambox-delete',
image = 'Ambox warning pn.svg'
},
content = {
class = 'ambox-content',
image = 'Ambox important.svg'
},
style = {
class = 'ambox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'ambox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'ambox-protection',
image = 'Semi-protection-shackle-keyhole.svg'
},
notice = {
class = 'ambox-notice',
image = 'Information icon4.svg'
}
},
default = 'notice',
allowBlankParams = {'talk', 'sect', 'date', 'issue', 'fix', 'hidden'},
allowSmall = true,
smallParam = 'left',
smallClass = 'mbox-small-left',
classes = {'metadata', 'ambox'},
imageEmptyCell = true,
imageCheckBlank = true,
imageSmallSize = '20x20px',
imageCellDiv = true,
useCollapsibleTextFields = true,
imageRightNone = true,
sectionDefault = 'article',
allowMainspaceCategories = true,
templateCategory = 'Article message templates',
templateCategoryRequireName = true,
templateErrorCategory = 'Article message templates with missing parameters',
templateErrorParamsToCheck = {'issue', 'fix'},
},
cmbox = {
types = {
speedy = {
class = 'cmbox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'cmbox-delete',
image = 'Ambox warning pn.svg'
},
content = {
class = 'cmbox-content',
image = 'Ambox important.svg'
},
style = {
class = 'cmbox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'cmbox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'cmbox-protection',
image = 'Semi-protection-shackle-keyhole.svg'
},
notice = {
class = 'cmbox-notice',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'cmbox'},
imageEmptyCell = true
},
fmbox = {
types = {
warning = {
class = 'fmbox-warning',
image = 'Ambox warning pn.svg'
},
editnotice = {
class = 'fmbox-editnotice',
image = 'Information icon4.svg'
},
system = {
class = 'fmbox-system',
image = 'Information icon4.svg'
}
},
default = 'system',
showInvalidTypeError = true,
classes = {'fmbox'},
imageEmptyCell = false,
imageRightNone = false
},
imbox = {
types = {
speedy = {
class = 'imbox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'imbox-delete',
image = 'Ambox warning pn.svg'
},
content = {
class = 'imbox-content',
image = 'Ambox important.svg'
},
style = {
class = 'imbox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'imbox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'imbox-protection',
image = 'Semi-protection-shackle-keyhole.svg'
},
license = {
class = 'imbox-license licensetpl',
image = 'Imbox license.png' -- @todo We need an SVG version of this
},
featured = {
class = 'imbox-featured',
image = 'Cscr-featured.svg'
},
notice = {
class = 'imbox-notice',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'imbox'},
imageEmptyCell = true,
below = true,
templateCategory = 'File message boxes'
},
ombox = {
types = {
speedy = {
class = 'ombox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'ombox-delete',
image = 'Ambox warning pn.svg'
},
content = {
class = 'ombox-content',
image = 'Ambox important.svg'
},
style = {
class = 'ombox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'ombox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'ombox-protection',
image = 'Semi-protection-shackle-keyhole.svg'
},
notice = {
class = 'ombox-notice',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'ombox'},
allowSmall = true,
imageEmptyCell = true,
imageRightNone = true
},
tmbox = {
types = {
speedy = {
class = 'tmbox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'tmbox-delete',
image = 'Ambox warning pn.svg'
},
content = {
class = 'tmbox-content',
image = 'Ambox important.svg'
},
style = {
class = 'tmbox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'tmbox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'tmbox-protection',
image = 'Semi-protection-shackle-keyhole.svg'
},
notice = {
class = 'tmbox-notice',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'tmbox'},
allowSmall = true,
imageRightNone = true,
imageEmptyCell = true,
imageEmptyCellStyle = true,
templateCategory = 'Talk message boxes'
}
}
c6bd9191861b23e474e12b19c694335c4bc3af5f
Template:Br separated entries
10
16
21
2023-12-27T05:38:59Z
CreepersNeedHugs
2
Created page with "{{<includeonly>safesubst:</includeonly>#invoke:Separated entries|br}}<noinclude> {{documentation}} </noinclude>"
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#invoke:Separated entries|br}}<noinclude>
{{documentation}}
</noinclude>
2019f7fc383259e70d66e43cbd97a43d20889f1b
Module:Separated entries
828
17
22
2023-12-27T05:40:05Z
CreepersNeedHugs
2
Created page with "-- This module takes positional parameters as input and concatenates them with -- an optional separator. The final separator (the "conjunction") can be -- specified independently, enabling natural-language lists like -- "foo, bar, baz and qux". The starting parameter can also be specified. local compressSparseArray = require('Module:TableTools').compressSparseArray local p = {} function p._main(args) local separator = args.separator -- Decode (convert to Unicode) HT..."
Scribunto
text/plain
-- This module takes positional parameters as input and concatenates them with
-- an optional separator. The final separator (the "conjunction") can be
-- specified independently, enabling natural-language lists like
-- "foo, bar, baz and qux". The starting parameter can also be specified.
local compressSparseArray = require('Module:TableTools').compressSparseArray
local p = {}
function p._main(args)
local separator = args.separator
-- Decode (convert to Unicode) HTML escape sequences, such as " " for space.
and mw.text.decode(args.separator) or ''
local conjunction = args.conjunction and mw.text.decode(args.conjunction) or separator
-- Discard values before the starting parameter.
local start = tonumber(args.start)
if start then
for i = 1, start - 1 do args[i] = nil end
end
-- Discard named parameters.
local values = compressSparseArray(args)
return mw.text.listToText(values, separator, conjunction)
end
local function makeInvokeFunction(separator, conjunction, first)
return function (frame)
local args = require('Module:Arguments').getArgs(frame)
args.separator = separator or args.separator
args.conjunction = conjunction or args.conjunction
args.first = first or args.first
return p._main(args)
end
end
p.main = makeInvokeFunction()
p.br = makeInvokeFunction('<br />')
p.comma = makeInvokeFunction(mw.message.new('comma-separator'):plain())
return p
e80231ff3de01afd7f62a94e0a34dc1e67504085
Module:TableTools
828
18
23
2023-12-27T05:40:54Z
CreepersNeedHugs
2
Created page with "------------------------------------------------------------------------------------ -- TableTools -- -- -- -- This module includes a number of functions for dealing with Lua tables. -- -- It is a meta-module, meant to be called from other Lua modules, and should not -- -- be called directly from #invoke...."
Scribunto
text/plain
------------------------------------------------------------------------------------
-- TableTools --
-- --
-- This module includes a number of functions for dealing with Lua tables. --
-- It is a meta-module, meant to be called from other Lua modules, and should not --
-- be called directly from #invoke. --
------------------------------------------------------------------------------------
local libraryUtil = require('libraryUtil')
local p = {}
-- Define often-used variables and functions.
local floor = math.floor
local infinity = math.huge
local checkType = libraryUtil.checkType
local checkTypeMulti = libraryUtil.checkTypeMulti
------------------------------------------------------------------------------------
-- isPositiveInteger
--
-- This function returns true if the given value is a positive integer, and false
-- if not. Although it doesn't operate on tables, it is included here as it is
-- useful for determining whether a given table key is in the array part or the
-- hash part of a table.
------------------------------------------------------------------------------------
function p.isPositiveInteger(v)
return type(v) == 'number' and v >= 1 and floor(v) == v and v < infinity
end
------------------------------------------------------------------------------------
-- isNan
--
-- This function returns true if the given number is a NaN value, and false if
-- not. Although it doesn't operate on tables, it is included here as it is useful
-- for determining whether a value can be a valid table key. Lua will generate an
-- error if a NaN is used as a table key.
------------------------------------------------------------------------------------
function p.isNan(v)
return type(v) == 'number' and v ~= v
end
------------------------------------------------------------------------------------
-- shallowClone
--
-- This returns a clone of a table. The value returned is a new table, but all
-- subtables and functions are shared. Metamethods are respected, but the returned
-- table will have no metatable of its own.
------------------------------------------------------------------------------------
function p.shallowClone(t)
checkType('shallowClone', 1, t, 'table')
local ret = {}
for k, v in pairs(t) do
ret[k] = v
end
return ret
end
------------------------------------------------------------------------------------
-- removeDuplicates
--
-- This removes duplicate values from an array. Non-positive-integer keys are
-- ignored. The earliest value is kept, and all subsequent duplicate values are
-- removed, but otherwise the array order is unchanged.
------------------------------------------------------------------------------------
function p.removeDuplicates(arr)
checkType('removeDuplicates', 1, arr, 'table')
local isNan = p.isNan
local ret, exists = {}, {}
for _, v in ipairs(arr) do
if isNan(v) then
-- NaNs can't be table keys, and they are also unique, so we don't need to check existence.
ret[#ret + 1] = v
else
if not exists[v] then
ret[#ret + 1] = v
exists[v] = true
end
end
end
return ret
end
------------------------------------------------------------------------------------
-- numKeys
--
-- This takes a table and returns an array containing the numbers of any numerical
-- keys that have non-nil values, sorted in numerical order.
------------------------------------------------------------------------------------
function p.numKeys(t)
checkType('numKeys', 1, t, 'table')
local isPositiveInteger = p.isPositiveInteger
local nums = {}
for k in pairs(t) do
if isPositiveInteger(k) then
nums[#nums + 1] = k
end
end
table.sort(nums)
return nums
end
------------------------------------------------------------------------------------
-- affixNums
--
-- This takes a table and returns an array containing the numbers of keys with the
-- specified prefix and suffix. For example, for the table
-- {a1 = 'foo', a3 = 'bar', a6 = 'baz'} and the prefix "a", affixNums will return
-- {1, 3, 6}.
------------------------------------------------------------------------------------
function p.affixNums(t, prefix, suffix)
checkType('affixNums', 1, t, 'table')
checkType('affixNums', 2, prefix, 'string', true)
checkType('affixNums', 3, suffix, 'string', true)
local function cleanPattern(s)
-- Cleans a pattern so that the magic characters ()%.[]*+-?^$ are interpreted literally.
return s:gsub('([%(%)%%%.%[%]%*%+%-%?%^%$])', '%%%1')
end
prefix = prefix or ''
suffix = suffix or ''
prefix = cleanPattern(prefix)
suffix = cleanPattern(suffix)
local pattern = '^' .. prefix .. '([1-9]%d*)' .. suffix .. '$'
local nums = {}
for k in pairs(t) do
if type(k) == 'string' then
local num = mw.ustring.match(k, pattern)
if num then
nums[#nums + 1] = tonumber(num)
end
end
end
table.sort(nums)
return nums
end
------------------------------------------------------------------------------------
-- numData
--
-- Given a table with keys like {"foo1", "bar1", "foo2", "baz2"}, returns a table
-- of subtables in the format
-- {[1] = {foo = 'text', bar = 'text'}, [2] = {foo = 'text', baz = 'text'}}.
-- Keys that don't end with an integer are stored in a subtable named "other". The
-- compress option compresses the table so that it can be iterated over with
-- ipairs.
------------------------------------------------------------------------------------
function p.numData(t, compress)
checkType('numData', 1, t, 'table')
checkType('numData', 2, compress, 'boolean', true)
local ret = {}
for k, v in pairs(t) do
local prefix, num = mw.ustring.match(tostring(k), '^([^0-9]*)([1-9][0-9]*)$')
if num then
num = tonumber(num)
local subtable = ret[num] or {}
if prefix == '' then
-- Positional parameters match the blank string; put them at the start of the subtable instead.
prefix = 1
end
subtable[prefix] = v
ret[num] = subtable
else
local subtable = ret.other or {}
subtable[k] = v
ret.other = subtable
end
end
if compress then
local other = ret.other
ret = p.compressSparseArray(ret)
ret.other = other
end
return ret
end
------------------------------------------------------------------------------------
-- compressSparseArray
--
-- This takes an array with one or more nil values, and removes the nil values
-- while preserving the order, so that the array can be safely traversed with
-- ipairs.
------------------------------------------------------------------------------------
function p.compressSparseArray(t)
checkType('compressSparseArray', 1, t, 'table')
local ret = {}
local nums = p.numKeys(t)
for _, num in ipairs(nums) do
ret[#ret + 1] = t[num]
end
return ret
end
------------------------------------------------------------------------------------
-- sparseIpairs
--
-- This is an iterator for sparse arrays. It can be used like ipairs, but can
-- handle nil values.
------------------------------------------------------------------------------------
function p.sparseIpairs(t)
checkType('sparseIpairs', 1, t, 'table')
local nums = p.numKeys(t)
local i = 0
local lim = #nums
return function ()
i = i + 1
if i <= lim then
local key = nums[i]
return key, t[key]
else
return nil, nil
end
end
end
------------------------------------------------------------------------------------
-- size
--
-- This returns the size of a key/value pair table. It will also work on arrays,
-- but for arrays it is more efficient to use the # operator.
------------------------------------------------------------------------------------
function p.size(t)
checkType('size', 1, t, 'table')
local i = 0
for _ in pairs(t) do
i = i + 1
end
return i
end
local function defaultKeySort(item1, item2)
-- "number" < "string", so numbers will be sorted before strings.
local type1, type2 = type(item1), type(item2)
if type1 ~= type2 then
return type1 < type2
elseif type1 == 'table' or type1 == 'boolean' or type1 == 'function' then
return tostring(item1) < tostring(item2)
else
return item1 < item2
end
end
------------------------------------------------------------------------------------
-- keysToList
--
-- Returns an array of the keys in a table, sorted using either a default
-- comparison function or a custom keySort function.
------------------------------------------------------------------------------------
function p.keysToList(t, keySort, checked)
if not checked then
checkType('keysToList', 1, t, 'table')
checkTypeMulti('keysToList', 2, keySort, {'function', 'boolean', 'nil'})
end
local arr = {}
local index = 1
for k in pairs(t) do
arr[index] = k
index = index + 1
end
if keySort ~= false then
keySort = type(keySort) == 'function' and keySort or defaultKeySort
table.sort(arr, keySort)
end
return arr
end
------------------------------------------------------------------------------------
-- sortedPairs
--
-- Iterates through a table, with the keys sorted using the keysToList function.
-- If there are only numerical keys, sparseIpairs is probably more efficient.
------------------------------------------------------------------------------------
function p.sortedPairs(t, keySort)
checkType('sortedPairs', 1, t, 'table')
checkType('sortedPairs', 2, keySort, 'function', true)
local arr = p.keysToList(t, keySort, true)
local i = 0
return function ()
i = i + 1
local key = arr[i]
if key ~= nil then
return key, t[key]
else
return nil, nil
end
end
end
------------------------------------------------------------------------------------
-- isArray
--
-- Returns true if the given value is a table and all keys are consecutive
-- integers starting at 1.
------------------------------------------------------------------------------------
function p.isArray(v)
if type(v) ~= 'table' then
return false
end
local i = 0
for _ in pairs(v) do
i = i + 1
if v[i] == nil then
return false
end
end
return true
end
------------------------------------------------------------------------------------
-- isArrayLike
--
-- Returns true if the given value is iterable and all keys are consecutive
-- integers starting at 1.
------------------------------------------------------------------------------------
function p.isArrayLike(v)
if not pcall(pairs, v) then
return false
end
local i = 0
for _ in pairs(v) do
i = i + 1
if v[i] == nil then
return false
end
end
return true
end
------------------------------------------------------------------------------------
-- invert
--
-- Transposes the keys and values in an array. For example, {"a", "b", "c"} ->
-- {a = 1, b = 2, c = 3}. Duplicates are not supported (result values refer to
-- the index of the last duplicate) and NaN values are ignored.
------------------------------------------------------------------------------------
function p.invert(arr)
checkType("invert", 1, arr, "table")
local isNan = p.isNan
local map = {}
for i, v in ipairs(arr) do
if not isNan(v) then
map[v] = i
end
end
return map
end
------------------------------------------------------------------------------------
-- listToSet
--
-- Creates a set from the array part of the table. Indexing the set by any of the
-- values of the array returns true. For example, {"a", "b", "c"} ->
-- {a = true, b = true, c = true}. NaN values are ignored as Lua considers them
-- never equal to any value (including other NaNs or even themselves).
------------------------------------------------------------------------------------
function p.listToSet(arr)
checkType("listToSet", 1, arr, "table")
local isNan = p.isNan
local set = {}
for _, v in ipairs(arr) do
if not isNan(v) then
set[v] = true
end
end
return set
end
------------------------------------------------------------------------------------
-- deepCopy
--
-- Recursive deep copy function. Preserves identities of subtables.
------------------------------------------------------------------------------------
local function _deepCopy(orig, includeMetatable, already_seen)
-- Stores copies of tables indexed by the original table.
already_seen = already_seen or {}
local copy = already_seen[orig]
if copy ~= nil then
return copy
end
if type(orig) == 'table' then
copy = {}
for orig_key, orig_value in pairs(orig) do
copy[_deepCopy(orig_key, includeMetatable, already_seen)] = _deepCopy(orig_value, includeMetatable, already_seen)
end
already_seen[orig] = copy
if includeMetatable then
local mt = getmetatable(orig)
if mt ~= nil then
local mt_copy = _deepCopy(mt, includeMetatable, already_seen)
setmetatable(copy, mt_copy)
already_seen[mt] = mt_copy
end
end
else -- number, string, boolean, etc
copy = orig
end
return copy
end
function p.deepCopy(orig, noMetatable, already_seen)
checkType("deepCopy", 3, already_seen, "table", true)
return _deepCopy(orig, not noMetatable, already_seen)
end
------------------------------------------------------------------------------------
-- sparseConcat
--
-- Concatenates all values in the table that are indexed by a number, in order.
-- sparseConcat{a, nil, c, d} => "acd"
-- sparseConcat{nil, b, c, d} => "bcd"
------------------------------------------------------------------------------------
function p.sparseConcat(t, sep, i, j)
local arr = {}
local arr_i = 0
for _, v in p.sparseIpairs(t) do
arr_i = arr_i + 1
arr[arr_i] = v
end
return table.concat(arr, sep, i, j)
end
------------------------------------------------------------------------------------
-- length
--
-- Finds the length of an array, or of a quasi-array with keys such as "data1",
-- "data2", etc., using an exponential search algorithm. It is similar to the
-- operator #, but may return a different value when there are gaps in the array
-- portion of the table. Intended to be used on data loaded with mw.loadData. For
-- other tables, use #.
-- Note: #frame.args in frame object always be set to 0, regardless of the number
-- of unnamed template parameters, so use this function for frame.args.
------------------------------------------------------------------------------------
function p.length(t, prefix)
-- requiring module inline so that [[Module:Exponential search]] which is
-- only needed by this one function doesn't get millions of transclusions
local expSearch = require("Module:Exponential search")
checkType('length', 1, t, 'table')
checkType('length', 2, prefix, 'string', true)
return expSearch(function (i)
local key
if prefix then
key = prefix .. tostring(i)
else
key = i
end
return t[key] ~= nil
end) or 0
end
------------------------------------------------------------------------------------
-- inArray
--
-- Returns true if valueToFind is a member of the array, and false otherwise.
------------------------------------------------------------------------------------
function p.inArray(arr, valueToFind)
checkType("inArray", 1, arr, "table")
-- if valueToFind is nil, error?
for _, v in ipairs(arr) do
if v == valueToFind then
return true
end
end
return false
end
return p
085e7094ac84eb0132ee65822cf3f69cd8ba3d81
Template:Character
10
19
24
2023-12-27T06:49:56Z
CreepersNeedHugs
2
Created page with "{{#invoke:infobox|infoboxTemplate|child={{{child|{{{embed|}}}}}} | bodyclass = biography vcard | above = <div class="fn" style="display:inline-block">{{#if:{{{name|}}}|{{{name}}}|{{PAGENAMEBASE}}}}</div> | abovestyle = font-size:125%; {{{abovestyle|}}} | subheaderstyle = font-size:125%; font-weight:bold; | subheader = {{#switch:{{{child|{{{embed|}}}}}}|yes=<!--empty when this infobox is embedded-->|#default={{#if:{{{nativename|}}}|{{#if:{{{nativenamelang|}}}|<di..."
wikitext
text/x-wiki
{{#invoke:infobox|infoboxTemplate|child={{{child|{{{embed|}}}}}}
| bodyclass = biography vcard
| above = <div class="fn" style="display:inline-block">{{#if:{{{name|}}}|{{{name}}}|{{PAGENAMEBASE}}}}</div>
| abovestyle = font-size:125%; {{{abovestyle|}}}
| subheaderstyle = font-size:125%; font-weight:bold;
| subheader = {{#switch:{{{child|{{{embed|}}}}}}|yes=<!--empty when this infobox is embedded-->|#default={{#if:{{{nativename|}}}|{{#if:{{{nativenamelang|}}}|<div class="nickname" lang="{{{native_name_lang}}}">}}{{{nativename}}}{{#if:{{{nativenamelang|}}}|</div>}} }} }}
| image = {{#invoke:InfoboxImage|InfoboxImage|image={{{image|}}}|size={{#ifeq:{{lc:{{{landscape|}}}}}|yes|{{min|300|{{#if:{{#ifexpr:{{{imagesize|}}}}}|300|imagesize|}}}}}}x200px|{{{imagesize|}}}|sizedefault=frameless|upright={{{imageupright|1}}}|alt={{{alt|}}}|suppressplaceholder=yes}}
| caption = {{{imagecaption|{{{caption|}}}}}}
| header2 = Names
| label3 = Full name
| data3 = {{{fullname|}}}
| label4 = Alias(es)
| data4 = {{{aliases|}}}
| label5 = Title(s)
| data5 = {{{title|}}}
| header6 = Biographical information
| label7 = Original timeline
| data7 = {{{originaltimeline|}}}
| label8 = Current timeline
| data8 = {{{currenttimeline|}}}
| label9 = Birthdate
| data9 = {{{birthdate|}}}
| label10 = Birth place
| data10 = {{{birthplace|}}}
| label11 = Birth name
| data11 = {{{birthname|}}}
| label12 = Death date
| data12 = {{{deathdate|}}}
| label13 = Death place
| data13 = {{{deathplace|}}}
| label15 = Cause of death
| data15 = {{{deathcause|}}}
| label16 = Burial date
| data16 = {{{burialdate|}}}
| label17 = Burial place
| data17 = {{{burialplace|}}}
| label19 = Residence
| data19 = {{{residence|}}}
| header20 = Descriptive information
| label21 = Species
| data21 = {{{species|}}}
| label22 = Gender
| data22 = {{{gender|{{{sex|}}}}}}
| label23 = Pronouns
| data23 = {{{pronouns|}}}
| label24 = Race/ethnicity
| data24 = {{{race|{{{ethnicity|}}}}}}
| label41 = Height
| data41 = {{Br separated entries|{{{heightmeters|{{{heightmetres|{{{heightm|}}}}}}}}} meters|{{{heightfeet|{{{heightft|}}}}}} feet{{#if:{{{heightinches|{{{heightin|}}}}}}|, {{{heightinches|{{{heightin|}}}}}}}}}}
| label42 = Weight
| data42 = {{Br separated entries|{{{weightkilograms|{{{heightkg|}}}}}} kilograms|{{{weightpounds|{{{weightlb|{{{weightlbs|}}}}}}}}} pounds{{#if:{{{weightounces|{{{weightoz|}}}}}}}}}}
| label43 = Hair colo{{#if:{{{haircolour|}}}|u}}r
| data43 = {{{haircolor|{{{haircolour|}}}}}}
| label44 = Eye colo{{#if:{{{eyecolour|}}}|u}}r
| data44 = {{{eyecolor|{{{eyecolour|}}}}}}
| header45 = Family information
| label46 = Parent(s)
| data46 = {{{parents|}}}
| label47 = Sibling(s)
| data47 = {{{siblings|}}}
| label54 = Romantic spouse(s)/partner(s)
| data54 = {{{spouse|{{{partner|}}}}}}
| label56 = Child(ren)
| data56 = {{{children|}}}
| label58 = Other family
| data58 = {{{relatives|}}}
| header59 = Affiliation(s)
| label60 = Citizenship
| data60 = {{{citizenship|}}}
| label61 = Occupation(s)
| data61 = {{{occupation|}}}
| label62 = Employer(s)
| data62 = {{{employer|}}}
| label63 = Affiliation(s)
| data63 = {{{affiliation|}}}
}}<!--
-->{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using {{if empty|{{{template_name|}}}|infobox person}} with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview = Page using [[Template:{{#if:{{{template_name|}}}|{{ucfirst:{{{template_name|}}}}}|Infobox person}}]] with unknown parameter "_VALUE_"|ignoreblank=n<!--this check deliberately flags empty unknown parameters; see talk, December 2022-->
| abovestyle | affiliation | aliases | alt | birthdate | birthname | birthplace | burialdate | burialplace | caption | child | children | citizenship | currenttimeline | deathcause | deathdate | deathplace | embed | employer | ethnicity | eyecolor | eyecolour | fullname | gender | haircolor | haircolour | heightfeet | heightft | heightin | heightinches | heightm | heightmeters | heightmetres | image | imagecaption | imagesize | imageupright | landscape | name | nativename | nativenamelang | nocatwdimage | occupation | originaltimeline | parents | partner | pronouns | race | relatives | residence | sex | siblings | species | spouse | title | weightkg | weightkilograms | weightlb | weightlbs | weightounces | weightoz | weightpounds }}<!--
-->{{#invoke:Check for clobbered parameters|check
| nested = 1
| child; embed
| caption; imagecaption
| gender; sex
| ethnicity; race
| heightm; heightmeters; heightmetres
| heightfeet; heightft
| heightin; heightinches
| weightkg; weightkilograms
| weightlb; weightlbs; weightpounds
| weightounces; weightoz
| haircolor; haircolour
| eyecolor; eyecolour
| partner; spouse
}}<includeonly>{{#ifeq:{{{child|{{{embed|}}}}}}|yes||{{Wikidata image|1={{{image|}}}|2={{{nocatwdimage|}}}}}}}</includeonly><noinclude>
{{documentation}}</noinclude>
51badcf5d3f72e370c3b1cb501b5507a1d476f18
30
24
2023-12-27T07:09:31Z
CreepersNeedHugs
2
wikitext
text/x-wiki
{{#invoke:infobox|infoboxTemplate|child={{{child|{{{embed|}}}}}}
| bodyclass = biography vcard
| above = <div class="fn" style="display:inline-block">{{#if:{{{name|}}}|{{{name}}}|{{PAGENAMEBASE}}}}</div>
| abovestyle = font-size:125%; {{{abovestyle|}}}
| subheaderstyle = font-size:125%; font-weight:bold;
| subheader = {{#switch:{{{child|{{{embed|}}}}}}|yes=<!--empty when this infobox is embedded-->|#default={{#if:{{{nativename|}}}|{{#if:{{{nativenamelang|}}}|<div class="nickname" lang="{{{native_name_lang}}}">}}{{{nativename}}}{{#if:{{{nativenamelang|}}}|</div>}} }} }}
| image = {{#invoke:InfoboxImage|InfoboxImage|image={{{image|}}}|size={{#ifeq:{{lc:{{{landscape|}}}}}|yes|{{min|300|{{#if:{{#ifexpr:{{{imagesize|}}}}}|300|imagesize|}}}}}}x200px|{{{imagesize|}}}|sizedefault=frameless|upright={{{imageupright|1}}}|alt={{{alt|}}}|suppressplaceholder=yes}}
| caption = {{{imagecaption|{{{caption|}}}}}}
| header2 = Names
| label3 = Full name
| data3 = {{{fullname|}}}
| label4 = Alias(es)
| data4 = {{{aliases|}}}
| label5 = Title(s)
| data5 = {{{title|}}}
| header6 = Biographical information
| label7 = Original timeline
| data7 = {{{originaltimeline|}}}
| label8 = Current timeline
| data8 = {{{currenttimeline|}}}
| label9 = Birthdate
| data9 = {{{birthdate|}}}
| label10 = Birth place
| data10 = {{{birthplace|}}}
| label11 = Birth name
| data11 = {{{birthname|}}}
| label12 = Death date
| data12 = {{{deathdate|}}}
| label13 = Death place
| data13 = {{{deathplace|}}}
| label15 = Cause of death
| data15 = {{{deathcause|}}}
| label16 = Burial date
| data16 = {{{burialdate|}}}
| label17 = Burial place
| data17 = {{{burialplace|}}}
| label19 = Residence
| data19 = {{{residence|}}}
| header20 = Descriptive information
| label21 = Species
| data21 = {{{species|}}}
| label22 = Gender
| data22 = {{{gender|{{{sex|}}}}}}
| label23 = Pronouns
| data23 = {{{pronouns|}}}
| label24 = Race/ethnicity
| data24 = {{{race|{{{ethnicity|}}}}}}
| label41 = Height
| data41 = {{Br separated entries
| 1 = {{#if:{{{heightmeters|{{{heightmetres|}}}}}}|{{{heightmeters|{{{heightmetres|}}}}}} {{#if:{{{heightmeters}}}|meters}} {{#if:{{{heightmetres|}}}|metres}}}}
| 2 = {{{heightfeet|}}} feet{{#if:{{{heightinches|}}}|, {{{heightinches|}}} inches}}
}}
| label42 = Weight
| data42 = {{Br separated entries
| 1 = {{{weightkilograms|}}} kilograms
| 2 = {{{weightpounds|}}} pounds{{#if:{{{weightounces|}}}|{{{weightounces|}}} ounces}}
}}
| label43 = Hair colo{{#if:{{{haircolour|}}}|u}}r
| data43 = {{{haircolor|{{{haircolour|}}}}}}
| label44 = Eye colo{{#if:{{{eyecolour|}}}|u}}r
| data44 = {{{eyecolor|{{{eyecolour|}}}}}}
| header45 = Family information
| label46 = Parent(s)
| data46 = {{{parents|}}}
| label47 = Sibling(s)
| data47 = {{{siblings|}}}
| label54 = Romantic spouse(s)/partner(s)
| data54 = {{{spouse|{{{partner|}}}}}}
| label56 = Child(ren)
| data56 = {{{children|}}}
| label58 = Other family
| data58 = {{{relatives|}}}
| header59 = Affiliation(s)
| label60 = Citizenship
| data60 = {{{citizenship|}}}
| label61 = Occupation(s)
| data61 = {{{occupation|}}}
| label62 = Employer(s)
| data62 = {{{employer|}}}
| label63 = Affiliation(s)
| data63 = {{{affiliation|}}}
}}<!--
-->{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using {{if empty|{{{template_name|}}}|character}} with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview = Page using [[Template:{{#if:{{{template_name|}}}|{{ucfirst:{{{template_name|}}}}}|Character}}]] with unknown parameter "_VALUE_"|ignoreblank=n<!--this check deliberately flags empty unknown parameters; see talk, December 2022-->
| abovestyle | affiliation | aliases | alt | birthdate | birthname | birthplace | burialdate | burialplace | caption | child | children | citizenship | currenttimeline | deathcause | deathdate | deathplace | embed | employer | ethnicity | eyecolor | eyecolour | fullname | gender | haircolor | haircolour | heightfeet | heightft | heightin | heightinches | heightm | heightmeters | heightmetres | image | imagecaption | imagesize | imageupright | landscape | name | nativename | nativenamelang | nocatwdimage | occupation | originaltimeline | parents | partner | pronouns | race | relatives | residence | sex | siblings | species | spouse | title | weightkg | weightkilograms | weightlb | weightlbs | weightounces | weightoz | weightpounds }}<!--
-->{{#invoke:Check for clobbered parameters|check
| nested = 1
| child; embed
| caption; imagecaption
| gender; sex
| ethnicity; race
| heightmeters; heightmetres
| haircolor; haircolour
| eyecolor; eyecolour
| partner; spouse
}}<includeonly>{{#ifeq:{{{child|{{{embed|}}}}}}|yes||{{Wikidata image|1={{{image|}}}|2={{{nocatwdimage|}}}}}}}</includeonly><noinclude>
{{documentation}}</noinclude>
be62ecd879bb4f181f078745c7ee62b2e511b9d9
31
30
2023-12-27T07:36:36Z
CreepersNeedHugs
2
wikitext
text/x-wiki
{{#invoke:infobox|infoboxTemplate|child={{{child|{{{embed|}}}}}}
| bodyclass = biography vcard
| above = <div class="fn" style="display:inline-block">{{#if:{{{name|}}}||{{{name|{{PAGENAMEBASE}}}}}}}</div>
| abovestyle = font-size:125%; {{{abovestyle|}}}
| subheaderstyle = font-size:125%; font-weight:bold;
| subheader = {{#switch:{{{child|{{{embed|}}}}}}|yes=<!--empty when this infobox is embedded-->|#default={{#if:{{{nativename|}}}|{{#if:{{{nativenamelang|}}}|<div class="nickname" lang="{{{native_name_lang}}}">}}{{{nativename}}}{{#if:{{{nativenamelang|}}}|</div>}} }} }}
| image = {{#invoke:InfoboxImage|InfoboxImage|image={{{image|}}}|size={{#ifeq:{{lc:{{{landscape|}}}}}|yes|{{min|300|{{#if:{{#ifexpr:{{{imagesize|}}}}}|300|imagesize|}}}}}}x200px|{{{imagesize|}}}|sizedefault=frameless|upright={{{imageupright|1}}}|alt={{{alt|}}}|suppressplaceholder=yes}}
| caption = {{{imagecaption|{{{caption|}}}}}}
| header2 = {{#if:{{{fullname|{{{aliases|{{{title|}}}}}}}}}|Names}}
| label3 = Full name
| data3 = {{{fullname|}}}
| label4 = Alias(es)
| data4 = {{{aliases|}}}
| label5 = Title(s)
| data5 = {{{title|}}}
| header6 = {{#if:{{{originaltimeline|{{{currenttimeline|{{{birthdate|{{{birthplace|{{{birthname|{{{deathdate|{{{deathplace|{{{deathcause|{{{burialdate|{{{burialplace|{{{residence}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||Biographical information}}
| label7 = Original timeline
| data7 = {{{originaltimeline|}}}
| label8 = Current timeline
| data8 = {{{currenttimeline|}}}
| label9 = Birthdate
| data9 = {{{birthdate|}}}
| label10 = Birth place
| data10 = {{{birthplace|}}}
| label11 = Birth name
| data11 = {{{birthname|}}}
| label12 = Death date
| data12 = {{{deathdate|}}}
| label13 = Death place
| data13 = {{{deathplace|}}}
| label15 = Cause of death
| data15 = {{{deathcause|}}}
| label16 = Burial date
| data16 = {{{burialdate|}}}
| label17 = Burial place
| data17 = {{{burialplace|}}}
| label19 = Residence
| data19 = {{{residence|}}}
| header20 = {{#if:{{{species|{{{gender|{{{pronouns|{{{race|{{{ethnicity|{{{heightmeters|{{{heightmetres|{{{heightfeet|{{{heightinches|{{{weightkilograms|{{{weightpounds|{{{weightounces|{{{haircolor|{{{haircolour|{{{eyecolor|{{{eyecolour}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||Descriptive information}}
| label21 = Species
| data21 = {{{species|}}}
| label22 = Gender
| data22 = {{{gender|{{{sex|}}}}}}
| label23 = Pronouns
| data23 = {{{pronouns|}}}
| label24 = Race/ethnicity
| data24 = {{{race|{{{ethnicity|}}}}}}
| label41 = Height
| data41 = {{Br separated entries
| 1 = {{#if:{{{heightmeters|{{{heightmetres|}}}}}}||{{{heightmeters|{{{heightmetres|}}}}}}||{{#if:{{{heightmeters}}}||meters}} {{#if:{{{heightmetres|}}}||metres}}}}
| 2 = {{#if:{{{heightfeet|{{{heightinches|}}}}}}|{{{{heightfeet|0}}} feet{{#if:{{{heightinches|}}}|, {{{heightinches|}}} inches}}}}
}}
| label42 = Weight
| data42 = {{Br separated entries
| 1 = {{#if:{{{weightkilograms|}}}|{{{weightkilograms|}}} kilograms}}
| 2 = {{#if:{{{weightpounds|{{{weightounces|}}}}}}|{{{weightpounds|0}}} pounds{{#if:{{{weightounces|}}}|, {{{weightounces|}}} ounces}}}}
}}
| label43 = Hair colo{{#if:{{{haircolour|}}}|u}}r
| data43 = {{{haircolor|{{{haircolour|}}}}}}
| label44 = Eye colo{{#if:{{{eyecolour|}}}|u}}r
| data44 = {{{eyecolor|{{{eyecolour|}}}}}}
| header45 = {{#if:{{{parents|{{{siblings|{{{spouse|{{{partner|{{{children|{{{relatives|}}}}}}}}}}}}}}}}}}|||Family information}}
| label46 = Parent(s)
| data46 = {{{parents|}}}
| label47 = Sibling(s)
| data47 = {{{siblings|}}}
| label54 = Romantic spouse(s)/partner(s)
| data54 = {{{spouse|{{{partner|}}}}}}
| label56 = Child(ren)
| data56 = {{{children|}}}
| label58 = Other family
| data58 = {{{relatives|}}}
| header59 = {{#if:{{{citizenship|{{{occupation|{{{employer|{{{affiliation|}}}}}}}}}}}}|||Affiliation(s)}}
| label60 = Citizenship
| data60 = {{{citizenship|}}}
| label61 = Occupation(s)
| data61 = {{{occupation|}}}
| label62 = Employer(s)
| data62 = {{{employer|}}}
| label63 = Affiliation(s)
| data63 = {{{affiliation|}}}
}}<!--
-->{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using {{if empty|{{{template_name|}}}|character}} with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview = Page using [[Template:{{#if:{{{template_name|}}}|{{ucfirst:{{{template_name|}}}}}|Character}}]] with unknown parameter "_VALUE_"|ignoreblank=n<!--this check deliberately flags empty unknown parameters; see talk, December 2022-->
| abovestyle | affiliation | aliases | alt | birthdate | birthname | birthplace | burialdate | burialplace | caption | child | children | citizenship | currenttimeline | deathcause | deathdate | deathplace | embed | employer | ethnicity | eyecolor | eyecolour | fullname | gender | haircolor | haircolour | heightfeet | heightft | heightin | heightinches | heightm | heightmeters | heightmetres | image | imagecaption | imagesize | imageupright | landscape | name | nativename | nativenamelang | nocatwdimage | occupation | originaltimeline | parents | partner | pronouns | race | relatives | residence | sex | siblings | species | spouse | title | weightkg | weightkilograms | weightlb | weightlbs | weightounces | weightoz | weightpounds }}<!--
-->{{#invoke:Check for clobbered parameters|check
| nested = 1
| child; embed
| caption; imagecaption
| gender; sex
| ethnicity; race
| heightmeters; heightmetres
| haircolor; haircolour
| eyecolor; eyecolour
| partner; spouse
}}<includeonly>{{#ifeq:{{{child|{{{embed|}}}}}}|yes||{{Wikidata image|1={{{image|}}}|2={{{nocatwdimage|}}}}}}}</includeonly><noinclude>
{{documentation}}</noinclude>
62ecb4504101541f33ef4e1d6d5521332b40c326
32
31
2023-12-27T08:00:09Z
CreepersNeedHugs
2
wikitext
text/x-wiki
{{#invoke:infobox|infoboxTemplate|child={{{child|{{{embed|}}}}}}
| bodyclass = biography vcard
| above = <div class="fn" style="display:inline-block">{{#if:{{{name|}}}||{{{name|{{PAGENAMEBASE}}}}}}}</div>
| abovestyle = font-size:125%; {{{abovestyle|}}}
| subheaderstyle = font-size:125%; font-weight:bold;
| subheader = {{#switch:{{{child|{{{embed|}}}}}}|yes=<!--empty when this infobox is embedded-->|#default={{#if:{{{nativename|}}}|{{#if:{{{nativenamelang|}}}|<div class="nickname" lang="{{{native_name_lang}}}">}}{{{nativename}}}{{#if:{{{nativenamelang|}}}|</div>}} }} }}
| image = {{#invoke:InfoboxImage|InfoboxImage|image={{{image|}}}|size={{#ifeq:{{lc:{{{landscape|}}}}}|yes|{{min|300|{{#if:{{#ifexpr:{{{imagesize|}}}}}|300|imagesize|}}}}}}x200px|{{{imagesize|}}}|sizedefault=frameless|upright={{{imageupright|1}}}|alt={{{alt|}}}|suppressplaceholder=yes}}
| caption = {{{imagecaption|{{{caption|}}}}}}
| header2 = {{#if:{{{fullname|{{{aliases|{{{title|}}}}}}}}}|Names}}
| label3 = Full name
| data3 = {{{fullname|}}}
| label4 = Alias(es)
| data4 = {{{aliases|}}}
| label5 = Title(s)
| data5 = {{{title|}}}
| header6 = {{#if:{{{originaltimeline|{{{currenttimeline|{{{birthdate|{{{birthplace|{{{birthname|{{{deathdate|{{{deathplace|{{{deathcause|{{{burialdate|{{{burialplace|{{{residence}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||Biographical information}}
| label7 = Original timeline
| data7 = {{{originaltimeline|}}}
| label8 = Current timeline
| data8 = {{{currenttimeline|}}}
| label9 = Birthdate
| data9 = {{{birthdate|}}}
| label10 = Birth place
| data10 = {{{birthplace|}}}
| label11 = Birth name
| data11 = {{{birthname|}}}
| label12 = Death date
| data12 = {{{deathdate|}}}
| label13 = Death place
| data13 = {{{deathplace|}}}
| label15 = Cause of death
| data15 = {{{deathcause|}}}
| label16 = Burial date
| data16 = {{{burialdate|}}}
| label17 = Burial place
| data17 = {{{burialplace|}}}
| label19 = Residence
| data19 = {{{residence|}}}
| header20 = {{#if:{{{species|{{{gender|{{{pronouns|{{{race|{{{ethnicity|{{{heightmeters|{{{heightmetres|{{{heightfeet|{{{heightinches|{{{weightkilograms|{{{weightpounds|{{{weightounces|{{{haircolor|{{{haircolour|{{{eyecolor|{{{eyecolour}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||Descriptive information}}
| label21 = Species
| data21 = {{{species|}}}
| label22 = Gender
| data22 = {{{gender|{{{sex|}}}}}}
| label23 = Pronouns
| data23 = {{{pronouns|}}}
| label24 = Race/ethnicity
| data24 = {{{race|{{{ethnicity|}}}}}}
| label41 = Height
| data41 = {{Br separated entries
| 1 = {{#if:{{{heightmetres|}}}|{{{heightmetres|}}} metres}}
| 2 = {{#if:{{{heightfeet|{{{heightinches|}}}}}}|{{{{heightfeet|0}}} feet{{#if:{{{heightinches|}}}|, {{{heightinches|}}} inches}}}}
}}
| label42 = Weight
| data42 = {{Br separated entries
| 1 = {{#if:{{{weightkilograms|}}}|{{{weightkilograms|}}} kilograms}}
| 2 = {{#if:{{{weightpounds|{{{weightounces|}}}}}}|{{{weightpounds|0}}} pounds{{#if:{{{weightounces|}}}|, {{{weightounces|}}} ounces}}}}
}}
| label43 = Hair colour
| data43 = {{{haircolour|}}}
| label44 = Eye colour
| data44 = {{{eyecolour|}}}
| header45 = {{#if:{{{parents|{{{siblings|{{{spouse|{{{partner|{{{children|{{{relatives|}}}}}}}}}}}}}}}}}}|||Family information}}
| label46 = Parent(s)
| data46 = {{{parents|}}}
| label47 = Sibling(s)
| data47 = {{{siblings|}}}
| label54 = Romantic spouse(s)/partner(s)
| data54 = {{{spouse|{{{partner|}}}}}}
| label56 = Child(ren)
| data56 = {{{children|}}}
| label58 = Other family
| data58 = {{{relatives|}}}
| header59 = {{#if:{{{citizenship|{{{occupation|{{{employer|{{{affiliation|}}}}}}}}}}}}|||Affiliation(s)}}
| label60 = Citizenship
| data60 = {{{citizenship|}}}
| label61 = Occupation(s)
| data61 = {{{occupation|}}}
| label62 = Employer(s)
| data62 = {{{employer|}}}
| label63 = Affiliation(s)
| data63 = {{{affiliation|}}}
}}<!--
-->{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using {{if empty|{{{template_name|}}}|character}} with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview = Page using [[Template:{{#if:{{{template_name|}}}|{{ucfirst:{{{template_name|}}}}}|Character}}]] with unknown parameter "_VALUE_"|ignoreblank=n<!--this check deliberately flags empty unknown parameters; see talk, December 2022-->
| abovestyle | affiliation | aliases | alt | birthdate | birthname | birthplace | burialdate | burialplace | caption | child | children | citizenship | currenttimeline | deathcause | deathdate | deathplace | embed | employer | ethnicity | eyecolour | fullname | gender | haircolour | heightfeet | heightinches | heightmetres | image | imagecaption | imagesize | imageupright | landscape | name | nativename | nativenamelang | nocatwdimage | occupation | originaltimeline | parents | partner | pronouns | race | relatives | residence | sex | siblings | species | spouse | title | weightkilograms | weightounces | weightpounds }}<!--
-->{{#invoke:Check for clobbered parameters|check
| nested = 1
| child; embed
| caption; imagecaption
| gender; sex
| ethnicity; race
| heightmeters; heightmetres
| haircolor; haircolour
| eyecolor; eyecolour
| partner; spouse
}}<includeonly>{{#ifeq:{{{child|{{{embed|}}}}}}|yes||{{Wikidata image|1={{{image|}}}|2={{{nocatwdimage|}}}}}}}</includeonly><noinclude>
{{documentation}}</noinclude>
7ec31f660882043f92ed4589ebae09255bf46385
35
32
2023-12-27T08:25:43Z
CreepersNeedHugs
2
wikitext
text/x-wiki
{{#invoke:infobox|infoboxTemplate|child={{{child|{{{embed|}}}}}}
| bodyclass = biography vcard
| above = <div class="fn" style="display:inline-block">{{#if:{{{name|}}}||{{{name|{{PAGENAMEBASE}}}}}}}</div>
| abovestyle = font-size:125%; {{{abovestyle|}}}
| subheaderstyle = font-size:125%; font-weight:bold;
| subheader = {{#switch:{{{child|{{{embed|}}}}}}|yes=<!--empty when this infobox is embedded-->|#default={{#if:{{{nativename|}}}|{{#if:{{{nativenamelang|}}}|<div class="nickname" lang="{{{native_name_lang}}}">}}{{{nativename}}}{{#if:{{{nativenamelang|}}}|</div>}} }} }}
| image = {{#invoke:InfoboxImage|InfoboxImage|image={{{image|}}}|size={{#ifeq:{{lc:{{{landscape|}}}}}|yes|{{min|300|{{#if:{{#ifexpr:{{{imagesize|}}}}}|300|imagesize|}}}}}}x200px|{{{imagesize|}}}|sizedefault=frameless|upright={{{imageupright|1}}}|alt={{{alt|}}}|suppressplaceholder=yes}}
| caption = {{{imagecaption|{{{caption|}}}}}}
| header2 = {{#if:{{{fullname|{{{aliases|{{{title|}}}}}}}}}|Names}}
| label3 = Full name
| data3 = {{{fullname|}}}
| label4 = Alias(es)
| data4 = {{{aliases|}}}
| label5 = Title(s)
| data5 = {{{title|}}}
| header6 = {{#if:{{{originaltimeline|{{{currenttimeline|{{{birthdate|{{{birthplace|{{{birthname|{{{deathdate|{{{deathplace|{{{deathcause|{{{burialdate|{{{burialplace|{{{residence}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||Biographical information}}
| label7 = Original timeline
| data7 = {{{originaltimeline|}}}
| label8 = Current timeline
| data8 = {{{currenttimeline|}}}
| label9 = Birthdate
| data9 = {{{birthdate|}}}
| label10 = Birth place
| data10 = {{{birthplace|}}}
| label11 = Birth name
| data11 = {{{birthname|}}}
| label12 = Death date
| data12 = {{{deathdate|}}}
| label13 = Death place
| data13 = {{{deathplace|}}}
| label15 = Cause of death
| data15 = {{{deathcause|}}}
| label16 = Burial date
| data16 = {{{burialdate|}}}
| label17 = Burial place
| data17 = {{{burialplace|}}}
| label19 = Residence
| data19 = {{{residence|}}}
| header20 = {{#if:{{{species|{{{gender|{{{pronouns|{{{race|{{{ethnicity|{{{heightmeters|{{{heightmetres|{{{heightfeet|{{{heightinches|{{{weightkilograms|{{{weightpounds|{{{weightounces|{{{haircolor|{{{haircolour|{{{eyecolor|{{{eyecolour}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||Descriptive information}}
| label21 = Species
| data21 = {{{species|}}}
| label22 = Gender
| data22 = {{{gender|{{{sex|}}}}}}
| label23 = Pronouns
| data23 = {{{pronouns|}}}
| label24 = Race/ethnicity
| data24 = {{{race|{{{ethnicity|}}}}}}
| label41 = Height
| data41 = {{Br separated entries
| 1 = {{#if:{{{heightmetres|}}}|{{{heightmetres|}}} metres}}
| 2 = {{#if:{{{heightfeet|{{{heightinches|}}}}}}|{{{{heightfeet|0}}} feet{{#if:{{{heightinches|}}}|, {{{heightinches|}}} inches}}}}
}}
| label42 = Weight
| data42 = {{Br separated entries
| 1 = {{#if:{{{weightkilograms|}}}|{{{weightkilograms|}}} kilograms}}
| 2 = {{#if:{{{weightpounds|{{{weightounces|}}}}}}|{{{weightpounds|0}}} pounds{{#if:{{{weightounces|}}}|, {{{weightounces|}}} ounces}}}}
}}
| label43 = Hair colour
| data43 = {{{haircolour|}}}
| label44 = Eye colour
| data44 = {{{eyecolour|}}}
| header45 = {{#if:{{{parents|{{{siblings|{{{spouse|{{{partner|{{{children|{{{relatives|}}}}}}}}}}}}}}}}}}|||Family information}}
| label46 = Parent(s)
| data46 = {{{parents|}}}
| label47 = Sibling(s)
| data47 = {{{siblings|}}}
| label54 = Spouse(s)/partner(s)
| data54 = {{{spouse|{{{partner|}}}}}}
| label56 = Child(ren)
| data56 = {{{children|}}}
| label58 = Other family
| data58 = {{{relatives|}}}
| header59 = {{#if:{{{citizenship|{{{occupation|{{{employer|{{{affiliation|}}}}}}}}}}}}|||Affiliation(s)}}
| label60 = Citizenship
| data60 = {{{citizenship|}}}
| label61 = Occupation(s)
| data61 = {{{occupation|}}}
| label62 = Employer(s)
| data62 = {{{employer|}}}
| label63 = Affiliation(s)
| data63 = {{{affiliation|}}}
}}<!--
-->{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using {{if empty|{{{template_name|}}}|character}} with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview = Page using [[Template:{{#if:{{{template_name|}}}|{{ucfirst:{{{template_name|}}}}}|Character}}]] with unknown parameter "_VALUE_"|ignoreblank=n<!--this check deliberately flags empty unknown parameters; see talk, December 2022-->
| abovestyle | affiliation | aliases | alt | birthdate | birthname | birthplace | burialdate | burialplace | caption | child | children | citizenship | currenttimeline | deathcause | deathdate | deathplace | embed | employer | ethnicity | eyecolour | fullname | gender | haircolour | heightfeet | heightinches | heightmetres | image | imagecaption | imagesize | imageupright | landscape | name | nativename | nativenamelang | nocatwdimage | occupation | originaltimeline | parents | partner | pronouns | race | relatives | residence | sex | siblings | species | spouse | title | weightkilograms | weightounces | weightpounds }}<!--
-->{{#invoke:Check for clobbered parameters|check
| nested = 1
| child; embed
| caption; imagecaption
| gender; sex
| ethnicity; race
| heightmeters; heightmetres
| haircolor; haircolour
| eyecolor; eyecolour
| partner; spouse
}}<noinclude>
{{documentation}}</noinclude>
54b5dc170a055cfcc5b2721818bb661999cdc0d8
36
35
2023-12-27T08:27:22Z
CreepersNeedHugs
2
wikitext
text/x-wiki
{{#invoke:infobox|infoboxTemplate|child={{{child|{{{embed|}}}}}}
| bodyclass = biography vcard
| above = <div class="fn" style="display:inline-block">{{#if:{{{name|}}}||{{{name|{{PAGENAMEBASE}}}}}}}</div>
| abovestyle = font-size:125%; {{{abovestyle|}}}
| subheaderstyle = font-size:125%; font-weight:bold;
| subheader = {{#switch:{{{child|{{{embed|}}}}}}|yes=<!--empty when this infobox is embedded-->|#default={{#if:{{{nativename|}}}|{{#if:{{{nativenamelang|}}}|<div class="nickname" lang="{{{native_name_lang}}}">}}{{{nativename}}}{{#if:{{{nativenamelang|}}}|</div>}} }} }}
| image = {{#invoke:InfoboxImage|InfoboxImage|image={{{image|}}}|size={{#ifeq:{{lc:{{{landscape|}}}}}|yes|{{min|300|{{#if:{{#ifexpr:{{{imagesize|}}}}}|300|imagesize|}}}}}}x200px|{{{imagesize|}}}|sizedefault=frameless|upright={{{imageupright|1}}}|alt={{{alt|}}}|suppressplaceholder=yes}}
| caption = {{{imagecaption|{{{caption|}}}}}}
| header2 = {{#if:{{{fullname|{{{aliases|{{{title|}}}}}}}}}|Names}}
| label3 = Full name
| data3 = {{{fullname|}}}
| label4 = Alias(es)
| data4 = {{{aliases|}}}
| label5 = Title(s)
| data5 = {{{title|}}}
| header6 = {{#if:{{{originaltimeline|{{{currenttimeline|{{{birthdate|{{{birthplace|{{{birthname|{{{deathdate|{{{deathplace|{{{deathcause|{{{burialdate|{{{burialplace|{{{residence}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||Biographical information}}
| label7 = Original timeline
| data7 = {{{originaltimeline|}}}
| label8 = Current timeline
| data8 = {{{currenttimeline|}}}
| label9 = Birthdate
| data9 = {{{birthdate|}}}
| label10 = Birth place
| data10 = {{{birthplace|}}}
| label11 = Birth name
| data11 = {{{birthname|}}}
| label12 = Death date
| data12 = {{{deathdate|}}}
| label13 = Death place
| data13 = {{{deathplace|}}}
| label15 = Cause of death
| data15 = {{{deathcause|}}}
| label16 = Burial date
| data16 = {{{burialdate|}}}
| label17 = Burial place
| data17 = {{{burialplace|}}}
| label19 = Residence
| data19 = {{{residence|}}}
| header20 = {{#if:{{{species|{{{gender|{{{pronouns|{{{race|{{{ethnicity|{{{heightmeters|{{{heightmetres|{{{heightfeet|{{{heightinches|{{{weightkilograms|{{{weightpounds|{{{weightounces|{{{haircolor|{{{haircolour|{{{eyecolor|{{{eyecolour}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||Descriptive information}}
| label21 = Species
| data21 = {{{species|}}}
| label22 = Gender
| data22 = {{{gender|{{{sex|}}}}}}
| label23 = Pronouns
| data23 = {{{pronouns|}}}
| label24 = Race/ethnicity
| data24 = {{{race|{{{ethnicity|}}}}}}
| label41 = Height
| data41 = {{Br separated entries
| 1 = {{#if:{{{heightmetres|}}}|{{{heightmetres|}}} metres}}
| 2 = {{#if:{{{heightfeet|{{{heightinches|}}}}}}|{{{heightfeet|0}}} feet{{#if:{{{heightinches|}}}|, {{{heightinches|}}} inches}}}}
}}
| label42 = Weight
| data42 = {{Br separated entries
| 1 = {{#if:{{{weightkilograms|}}}|{{{weightkilograms|}}} kilograms}}
| 2 = {{#if:{{{weightpounds|{{{weightounces|}}}}}}|{{{weightpounds|0}}} pounds{{#if:{{{weightounces|}}}|, {{{weightounces|}}} ounces}}}}
}}
| label43 = Hair colour
| data43 = {{{haircolour|}}}
| label44 = Eye colour
| data44 = {{{eyecolour|}}}
| header45 = {{#if:{{{parents|{{{siblings|{{{spouse|{{{partner|{{{children|{{{relatives|}}}}}}}}}}}}}}}}}}|||Family information}}
| label46 = Parent(s)
| data46 = {{{parents|}}}
| label47 = Sibling(s)
| data47 = {{{siblings|}}}
| label54 = Spouse(s)/partner(s)
| data54 = {{{spouse|{{{partner|}}}}}}
| label56 = Child(ren)
| data56 = {{{children|}}}
| label58 = Other family
| data58 = {{{relatives|}}}
| header59 = {{#if:{{{citizenship|{{{occupation|{{{employer|{{{affiliation|}}}}}}}}}}}}|||Affiliation(s)}}
| label60 = Citizenship
| data60 = {{{citizenship|}}}
| label61 = Occupation(s)
| data61 = {{{occupation|}}}
| label62 = Employer(s)
| data62 = {{{employer|}}}
| label63 = Affiliation(s)
| data63 = {{{affiliation|}}}
}}<!--
-->{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using {{if empty|{{{template_name|}}}|character}} with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview = Page using [[Template:{{#if:{{{template_name|}}}|{{ucfirst:{{{template_name|}}}}}|Character}}]] with unknown parameter "_VALUE_"|ignoreblank=n<!--this check deliberately flags empty unknown parameters; see talk, December 2022-->
| abovestyle | affiliation | aliases | alt | birthdate | birthname | birthplace | burialdate | burialplace | caption | child | children | citizenship | currenttimeline | deathcause | deathdate | deathplace | embed | employer | ethnicity | eyecolour | fullname | gender | haircolour | heightfeet | heightinches | heightmetres | image | imagecaption | imagesize | imageupright | landscape | name | nativename | nativenamelang | nocatwdimage | occupation | originaltimeline | parents | partner | pronouns | race | relatives | residence | sex | siblings | species | spouse | title | weightkilograms | weightounces | weightpounds }}<!--
-->{{#invoke:Check for clobbered parameters|check
| nested = 1
| child; embed
| caption; imagecaption
| gender; sex
| ethnicity; race
| heightmeters; heightmetres
| haircolor; haircolour
| eyecolor; eyecolour
| partner; spouse
}}<noinclude>
{{documentation}}</noinclude>
8a85e973d68e30856717de2e56a978b7a5d469f8
37
36
2023-12-27T08:29:04Z
CreepersNeedHugs
2
wikitext
text/x-wiki
{{#invoke:infobox|infoboxTemplate|child={{{child|{{{embed|}}}}}}
| bodyclass = biography vcard
| above = <div class="fn" style="display:inline-block">{{#if:{{{name|}}}||{{{name|{{PAGENAMEBASE}}}}}}}</div>
| abovestyle = font-size:125%; {{{abovestyle|}}}
| subheaderstyle = font-size:125%; font-weight:bold;
| subheader = {{#switch:{{{child|{{{embed|}}}}}}|yes=<!--empty when this infobox is embedded-->|#default={{#if:{{{nativename|}}}|{{#if:{{{nativenamelang|}}}|<div class="nickname" lang="{{{native_name_lang}}}">}}{{{nativename}}}{{#if:{{{nativenamelang|}}}|</div>}} }} }}
| image = {{#invoke:InfoboxImage|InfoboxImage|image={{{image|}}}|size={{#ifeq:{{lc:{{{landscape|}}}}}|yes|{{min|300|{{#if:{{#ifexpr:{{{imagesize|}}}}}|300|imagesize|}}}}}}x200px|{{{imagesize|}}}|sizedefault=frameless|upright={{{imageupright|1}}}|alt={{{alt|}}}|suppressplaceholder=yes}}
| caption = {{{imagecaption|{{{caption|}}}}}}
| header2 = {{#if:{{{fullname|{{{aliases|{{{title|}}}}}}}}}|Names}}
| label3 = Full name
| data3 = {{{fullname|}}}
| label4 = Alias(es)
| data4 = {{{aliases|}}}
| label5 = Title(s)
| data5 = {{{title|}}}
| header6 = {{#if:{{{originaltimeline|{{{currenttimeline|{{{birthdate|{{{birthplace|{{{birthname|{{{deathdate|{{{deathplace|{{{deathcause|{{{burialdate|{{{burialplace|{{{residence}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|Biographical information}}
| label7 = Original timeline
| data7 = {{{originaltimeline|}}}
| label8 = Current timeline
| data8 = {{{currenttimeline|}}}
| label9 = Birthdate
| data9 = {{{birthdate|}}}
| label10 = Birth place
| data10 = {{{birthplace|}}}
| label11 = Birth name
| data11 = {{{birthname|}}}
| label12 = Death date
| data12 = {{{deathdate|}}}
| label13 = Death place
| data13 = {{{deathplace|}}}
| label15 = Cause of death
| data15 = {{{deathcause|}}}
| label16 = Burial date
| data16 = {{{burialdate|}}}
| label17 = Burial place
| data17 = {{{burialplace|}}}
| label19 = Residence
| data19 = {{{residence|}}}
| header20 = {{#if:{{{species|{{{gender|{{{pronouns|{{{race|{{{ethnicity|{{{heightmeters|{{{heightmetres|{{{heightfeet|{{{heightinches|{{{weightkilograms|{{{weightpounds|{{{weightounces|{{{haircolor|{{{haircolour|{{{eyecolor|{{{eyecolour}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|Descriptive information}}
| label21 = Species
| data21 = {{{species|}}}
| label22 = Gender
| data22 = {{{gender|{{{sex|}}}}}}
| label23 = Pronouns
| data23 = {{{pronouns|}}}
| label24 = Race/ethnicity
| data24 = {{{race|{{{ethnicity|}}}}}}
| label41 = Height
| data41 = {{Br separated entries
| 1 = {{#if:{{{heightmetres|}}}|{{{heightmetres|}}} metres}}
| 2 = {{#if:{{{heightfeet|{{{heightinches|}}}}}}|{{{heightfeet|0}}} feet{{#if:{{{heightinches|}}}|, {{{heightinches|}}} inches}}}}
}}
| label42 = Weight
| data42 = {{Br separated entries
| 1 = {{#if:{{{weightkilograms|}}}|{{{weightkilograms|}}} kilograms}}
| 2 = {{#if:{{{weightpounds|{{{weightounces|}}}}}}|{{{weightpounds|0}}} pounds{{#if:{{{weightounces|}}}|, {{{weightounces|}}} ounces}}}}
}}
| label43 = Hair colour
| data43 = {{{haircolour|}}}
| label44 = Eye colour
| data44 = {{{eyecolour|}}}
| header45 = {{#if:{{{parents|{{{siblings|{{{spouse|{{{partner|{{{children|{{{relatives|}}}}}}}}}}}}}}}}}}|Family information}}
| label46 = Parent(s)
| data46 = {{{parents|}}}
| label47 = Sibling(s)
| data47 = {{{siblings|}}}
| label54 = Spouse(s)/partner(s)
| data54 = {{{spouse|{{{partner|}}}}}}
| label56 = Child(ren)
| data56 = {{{children|}}}
| label58 = Other family
| data58 = {{{relatives|}}}
| header59 = {{#if:{{{citizenship|{{{occupation|{{{employer|{{{affiliation|}}}}}}}}}}}}|Affiliation(s)}}
| label60 = Citizenship
| data60 = {{{citizenship|}}}
| label61 = Occupation(s)
| data61 = {{{occupation|}}}
| label62 = Employer(s)
| data62 = {{{employer|}}}
| label63 = Affiliation(s)
| data63 = {{{affiliation|}}}
}}<!--
-->{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using {{if empty|{{{template_name|}}}|character}} with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview = Page using [[Template:{{#if:{{{template_name|}}}|{{ucfirst:{{{template_name|}}}}}|Character}}]] with unknown parameter "_VALUE_"|ignoreblank=n<!--this check deliberately flags empty unknown parameters; see talk, December 2022-->
| abovestyle | affiliation | aliases | alt | birthdate | birthname | birthplace | burialdate | burialplace | caption | child | children | citizenship | currenttimeline | deathcause | deathdate | deathplace | embed | employer | ethnicity | eyecolour | fullname | gender | haircolour | heightfeet | heightinches | heightmetres | image | imagecaption | imagesize | imageupright | landscape | name | nativename | nativenamelang | nocatwdimage | occupation | originaltimeline | parents | partner | pronouns | race | relatives | residence | sex | siblings | species | spouse | title | weightkilograms | weightounces | weightpounds }}<!--
-->{{#invoke:Check for clobbered parameters|check
| nested = 1
| child; embed
| caption; imagecaption
| gender; sex
| ethnicity; race
| heightmeters; heightmetres
| haircolor; haircolour
| eyecolor; eyecolour
| partner; spouse
}}<noinclude>
{{documentation}}</noinclude>
4f1ee1d390235f7c8ce8e4d26215c5cc8977bb29
38
37
2023-12-27T08:31:00Z
CreepersNeedHugs
2
wikitext
text/x-wiki
{{#invoke:infobox|infoboxTemplate|child={{{child|{{{embed|}}}}}}
| bodyclass = biography vcard
| above = <div class="fn" style="display:inline-block">{{#if:{{{name|}}}||{{{name|{{PAGENAMEBASE}}}}}}}</div>
| abovestyle = font-size:125%; {{{abovestyle|}}}
| subheaderstyle = font-size:125%; font-weight:bold;
| subheader = {{#switch:{{{child|{{{embed|}}}}}}|yes=<!--empty when this infobox is embedded-->|#default={{#if:{{{nativename|}}}|{{#if:{{{nativenamelang|}}}|<div class="nickname" lang="{{{native_name_lang}}}">}}{{{nativename}}}{{#if:{{{nativenamelang|}}}|</div>}} }} }}
| image = {{#invoke:InfoboxImage|InfoboxImage|image={{{image|}}}|size={{#ifeq:{{lc:{{{landscape|}}}}}|yes|{{min|300|{{#if:{{#ifexpr:{{{imagesize|}}}}}|300|imagesize|}}}}}}x200px|{{{imagesize|}}}|sizedefault=frameless|upright={{{imageupright|1}}}|alt={{{alt|}}}|suppressplaceholder=yes}}
| caption = {{{imagecaption|{{{caption|}}}}}}
| header2 = {{#if:{{{fullname|{{{aliases|{{{title|}}}}}}}}}|Names}}
| label3 = Full name
| data3 = {{{fullname|}}}
| label4 = Alias(es)
| data4 = {{{aliases|}}}
| label5 = Title(s)
| data5 = {{{title|}}}
| header6 = {{#if:{{{originaltimeline|{{{currenttimeline|{{{birthdate|{{{birthplace|{{{birthname|{{{deathdate|{{{deathplace|{{{deathcause|{{{burialdate|{{{burialplace|{{{residence}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||Biographical information}}
| label7 = Original timeline
| data7 = {{{originaltimeline|}}}
| label8 = Current timeline
| data8 = {{{currenttimeline|}}}
| label9 = Birthdate
| data9 = {{{birthdate|}}}
| label10 = Birth place
| data10 = {{{birthplace|}}}
| label11 = Birth name
| data11 = {{{birthname|}}}
| label12 = Death date
| data12 = {{{deathdate|}}}
| label13 = Death place
| data13 = {{{deathplace|}}}
| label15 = Cause of death
| data15 = {{{deathcause|}}}
| label16 = Burial date
| data16 = {{{burialdate|}}}
| label17 = Burial place
| data17 = {{{burialplace|}}}
| label19 = Residence
| data19 = {{{residence|}}}
| header20 = {{#if:{{{species|{{{gender|{{{pronouns|{{{race|{{{ethnicity|{{{heightmeters|{{{heightmetres|{{{heightfeet|{{{heightinches|{{{weightkilograms|{{{weightpounds|{{{weightounces|{{{haircolor|{{{haircolour|{{{eyecolor|{{{eyecolour}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||Descriptive information}}
| label21 = Species
| data21 = {{{species|}}}
| label22 = Gender
| data22 = {{{gender|{{{sex|}}}}}}
| label23 = Pronouns
| data23 = {{{pronouns|}}}
| label24 = Race/ethnicity
| data24 = {{{race|{{{ethnicity|}}}}}}
| label41 = Height
| data41 = {{Br separated entries
| 1 = {{#if:{{{heightmetres|}}}|{{{heightmetres|}}} metres}}
| 2 = {{#if:{{{heightfeet|{{{heightinches|}}}}}}|{{{heightfeet|0}}} feet{{#if:{{{heightinches|}}}|, {{{heightinches|}}} inches}}}}
}}
| label42 = Weight
| data42 = {{Br separated entries
| 1 = {{#if:{{{weightkilograms|}}}|{{{weightkilograms|}}} kilograms}}
| 2 = {{#if:{{{weightpounds|{{{weightounces|}}}}}}|{{{weightpounds|0}}} pounds{{#if:{{{weightounces|}}}|, {{{weightounces|}}} ounces}}}}
}}
| label43 = Hair colour
| data43 = {{{haircolour|}}}
| label44 = Eye colour
| data44 = {{{eyecolour|}}}
| header45 = {{#if:{{{parents|{{{siblings|{{{spouse|{{{partner|{{{children|{{{relatives|}}}}}}}}}}}}}}}}}}|Family information}}
| label46 = Parent(s)
| data46 = {{{parents|}}}
| label47 = Sibling(s)
| data47 = {{{siblings|}}}
| label54 = Spouse(s)/partner(s)
| data54 = {{{spouse|{{{partner|}}}}}}
| label56 = Child(ren)
| data56 = {{{children|}}}
| label58 = Other family
| data58 = {{{relatives|}}}
| header59 = {{#if:{{{citizenship|{{{occupation|{{{employer|{{{affiliation|}}}}}}}}}}}}|Affiliation(s)}}
| label60 = Citizenship
| data60 = {{{citizenship|}}}
| label61 = Occupation(s)
| data61 = {{{occupation|}}}
| label62 = Employer(s)
| data62 = {{{employer|}}}
| label63 = Affiliation(s)
| data63 = {{{affiliation|}}}
}}<!--
-->{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using {{if empty|{{{template_name|}}}|character}} with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview = Page using [[Template:{{#if:{{{template_name|}}}|{{ucfirst:{{{template_name|}}}}}|Character}}]] with unknown parameter "_VALUE_"|ignoreblank=n<!--this check deliberately flags empty unknown parameters; see talk, December 2022-->
| abovestyle | affiliation | aliases | alt | birthdate | birthname | birthplace | burialdate | burialplace | caption | child | children | citizenship | currenttimeline | deathcause | deathdate | deathplace | embed | employer | ethnicity | eyecolour | fullname | gender | haircolour | heightfeet | heightinches | heightmetres | image | imagecaption | imagesize | imageupright | landscape | name | nativename | nativenamelang | nocatwdimage | occupation | originaltimeline | parents | partner | pronouns | race | relatives | residence | sex | siblings | species | spouse | title | weightkilograms | weightounces | weightpounds }}<!--
-->{{#invoke:Check for clobbered parameters|check
| nested = 1
| child; embed
| caption; imagecaption
| gender; sex
| ethnicity; race
| heightmeters; heightmetres
| haircolor; haircolour
| eyecolor; eyecolour
| partner; spouse
}}<noinclude>
{{documentation}}</noinclude>
9a56feb2d7313b0b7813130f39677beeecab81f3
39
38
2023-12-27T08:31:46Z
CreepersNeedHugs
2
wikitext
text/x-wiki
{{#invoke:infobox|infoboxTemplate|child={{{child|{{{embed|}}}}}}
| bodyclass = biography vcard
| above = <div class="fn" style="display:inline-block">{{#if:{{{name|}}}||{{{name|{{PAGENAMEBASE}}}}}}}</div>
| abovestyle = font-size:125%; {{{abovestyle|}}}
| subheaderstyle = font-size:125%; font-weight:bold;
| subheader = {{#switch:{{{child|{{{embed|}}}}}}|yes=<!--empty when this infobox is embedded-->|#default={{#if:{{{nativename|}}}|{{#if:{{{nativenamelang|}}}|<div class="nickname" lang="{{{native_name_lang}}}">}}{{{nativename}}}{{#if:{{{nativenamelang|}}}|</div>}} }} }}
| image = {{#invoke:InfoboxImage|InfoboxImage|image={{{image|}}}|size={{#ifeq:{{lc:{{{landscape|}}}}}|yes|{{min|300|{{#if:{{#ifexpr:{{{imagesize|}}}}}|300|imagesize|}}}}}}x200px|{{{imagesize|}}}|sizedefault=frameless|upright={{{imageupright|1}}}|alt={{{alt|}}}|suppressplaceholder=yes}}
| caption = {{{imagecaption|{{{caption|}}}}}}
| header2 = {{#if:{{{fullname|{{{aliases|{{{title|}}}}}}}}}|Names}}
| label3 = Full name
| data3 = {{{fullname|}}}
| label4 = Alias(es)
| data4 = {{{aliases|}}}
| label5 = Title(s)
| data5 = {{{title|}}}
| header6 = {{#if:{{{originaltimeline|{{{currenttimeline|{{{birthdate|{{{birthplace|{{{birthname|{{{deathdate|{{{deathplace|{{{deathcause|{{{burialdate|{{{burialplace|{{{residence}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|||Biographical information}}
| label7 = Original timeline
| data7 = {{{originaltimeline|}}}
| label8 = Current timeline
| data8 = {{{currenttimeline|}}}
| label9 = Birthdate
| data9 = {{{birthdate|}}}
| label10 = Birth place
| data10 = {{{birthplace|}}}
| label11 = Birth name
| data11 = {{{birthname|}}}
| label12 = Death date
| data12 = {{{deathdate|}}}
| label13 = Death place
| data13 = {{{deathplace|}}}
| label15 = Cause of death
| data15 = {{{deathcause|}}}
| label16 = Burial date
| data16 = {{{burialdate|}}}
| label17 = Burial place
| data17 = {{{burialplace|}}}
| label19 = Residence
| data19 = {{{residence|}}}
| header20 = {{#if:{{{species|{{{gender|{{{pronouns|{{{race|{{{ethnicity|{{{heightmeters|{{{heightmetres|{{{heightfeet|{{{heightinches|{{{weightkilograms|{{{weightpounds|{{{weightounces|{{{haircolor|{{{haircolour|{{{eyecolor|{{{eyecolour}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|||Descriptive information}}
| label21 = Species
| data21 = {{{species|}}}
| label22 = Gender
| data22 = {{{gender|{{{sex|}}}}}}
| label23 = Pronouns
| data23 = {{{pronouns|}}}
| label24 = Race/ethnicity
| data24 = {{{race|{{{ethnicity|}}}}}}
| label41 = Height
| data41 = {{Br separated entries
| 1 = {{#if:{{{heightmetres|}}}|{{{heightmetres|}}} metres}}
| 2 = {{#if:{{{heightfeet|{{{heightinches|}}}}}}|{{{heightfeet|0}}} feet{{#if:{{{heightinches|}}}|, {{{heightinches|}}} inches}}}}
}}
| label42 = Weight
| data42 = {{Br separated entries
| 1 = {{#if:{{{weightkilograms|}}}|{{{weightkilograms|}}} kilograms}}
| 2 = {{#if:{{{weightpounds|{{{weightounces|}}}}}}|{{{weightpounds|0}}} pounds{{#if:{{{weightounces|}}}|, {{{weightounces|}}} ounces}}}}
}}
| label43 = Hair colour
| data43 = {{{haircolour|}}}
| label44 = Eye colour
| data44 = {{{eyecolour|}}}
| header45 = {{#if:{{{parents|{{{siblings|{{{spouse|{{{partner|{{{children|{{{relatives|}}}}}}}}}}}}}}}}}}|Family information}}
| label46 = Parent(s)
| data46 = {{{parents|}}}
| label47 = Sibling(s)
| data47 = {{{siblings|}}}
| label54 = Spouse(s)/partner(s)
| data54 = {{{spouse|{{{partner|}}}}}}
| label56 = Child(ren)
| data56 = {{{children|}}}
| label58 = Other family
| data58 = {{{relatives|}}}
| header59 = {{#if:{{{citizenship|{{{occupation|{{{employer|{{{affiliation|}}}}}}}}}}}}|Affiliation(s)}}
| label60 = Citizenship
| data60 = {{{citizenship|}}}
| label61 = Occupation(s)
| data61 = {{{occupation|}}}
| label62 = Employer(s)
| data62 = {{{employer|}}}
| label63 = Affiliation(s)
| data63 = {{{affiliation|}}}
}}<!--
-->{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using {{if empty|{{{template_name|}}}|character}} with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview = Page using [[Template:{{#if:{{{template_name|}}}|{{ucfirst:{{{template_name|}}}}}|Character}}]] with unknown parameter "_VALUE_"|ignoreblank=n<!--this check deliberately flags empty unknown parameters; see talk, December 2022-->
| abovestyle | affiliation | aliases | alt | birthdate | birthname | birthplace | burialdate | burialplace | caption | child | children | citizenship | currenttimeline | deathcause | deathdate | deathplace | embed | employer | ethnicity | eyecolour | fullname | gender | haircolour | heightfeet | heightinches | heightmetres | image | imagecaption | imagesize | imageupright | landscape | name | nativename | nativenamelang | nocatwdimage | occupation | originaltimeline | parents | partner | pronouns | race | relatives | residence | sex | siblings | species | spouse | title | weightkilograms | weightounces | weightpounds }}<!--
-->{{#invoke:Check for clobbered parameters|check
| nested = 1
| child; embed
| caption; imagecaption
| gender; sex
| ethnicity; race
| heightmeters; heightmetres
| haircolor; haircolour
| eyecolor; eyecolour
| partner; spouse
}}<noinclude>
{{documentation}}</noinclude>
a1f77373f910819d066822df3f2f618f7a3cc7ce
40
39
2023-12-27T08:33:46Z
CreepersNeedHugs
2
wikitext
text/x-wiki
{{#invoke:infobox|infoboxTemplate|child={{{child|{{{embed|}}}}}}
| bodyclass = biography vcard
| above = <div class="fn" style="display:inline-block">{{#if:{{{name|}}}||{{{name|{{PAGENAMEBASE}}}}}}}</div>
| abovestyle = font-size:125%; {{{abovestyle|}}}
| subheaderstyle = font-size:125%; font-weight:bold;
| subheader = {{#switch:{{{child|{{{embed|}}}}}}|yes=<!--empty when this infobox is embedded-->|#default={{#if:{{{nativename|}}}|{{#if:{{{nativenamelang|}}}|<div class="nickname" lang="{{{native_name_lang}}}">}}{{{nativename}}}{{#if:{{{nativenamelang|}}}|</div>}} }} }}
| image = {{#invoke:InfoboxImage|InfoboxImage|image={{{image|}}}|size={{#ifeq:{{lc:{{{landscape|}}}}}|yes|{{min|300|{{#if:{{#ifexpr:{{{imagesize|}}}}}|300|imagesize|}}}}}}x200px|{{{imagesize|}}}|sizedefault=frameless|upright={{{imageupright|1}}}|alt={{{alt|}}}|suppressplaceholder=yes}}
| caption = {{{imagecaption|{{{caption|}}}}}}
| header2 = {{#if:{{{fullname|{{{aliases|{{{title|}}}}}}}}}|Names}}
| label3 = Full name
| data3 = {{{fullname|}}}
| label4 = Alias(es)
| data4 = {{{aliases|}}}
| label5 = Title(s)
| data5 = {{{title|}}}
| header6 = {{#if:{{{originaltimeline|{{{currenttimeline|{{{birthdate|{{{birthplace|{{{birthname|{{{deathdate|{{{deathplace|{{{deathcause|{{{burialdate|{{{burialplace|{{{residence|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|Biographical information}}
| label7 = Original timeline
| data7 = {{{originaltimeline|}}}
| label8 = Current timeline
| data8 = {{{currenttimeline|}}}
| label9 = Birthdate
| data9 = {{{birthdate|}}}
| label10 = Birth place
| data10 = {{{birthplace|}}}
| label11 = Birth name
| data11 = {{{birthname|}}}
| label12 = Death date
| data12 = {{{deathdate|}}}
| label13 = Death place
| data13 = {{{deathplace|}}}
| label15 = Cause of death
| data15 = {{{deathcause|}}}
| label16 = Burial date
| data16 = {{{burialdate|}}}
| label17 = Burial place
| data17 = {{{burialplace|}}}
| label19 = Residence
| data19 = {{{residence|}}}
| header20 = {{#if:{{{species|{{{gender|{{{pronouns|{{{race|{{{ethnicity|{{{heightmeters|{{{heightmetres|{{{heightfeet|{{{heightinches|{{{weightkilograms|{{{weightpounds|{{{weightounces|{{{haircolor|{{{haircolour|{{{eyecolor|{{{eyecolour|}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|Descriptive information}}
| label21 = Species
| data21 = {{{species|}}}
| label22 = Gender
| data22 = {{{gender|{{{sex|}}}}}}
| label23 = Pronouns
| data23 = {{{pronouns|}}}
| label24 = Race/ethnicity
| data24 = {{{race|{{{ethnicity|}}}}}}
| label41 = Height
| data41 = {{Br separated entries
| 1 = {{#if:{{{heightmetres|}}}|{{{heightmetres|}}} metres}}
| 2 = {{#if:{{{heightfeet|{{{heightinches|}}}}}}|{{{heightfeet|0}}} feet{{#if:{{{heightinches|}}}|, {{{heightinches|}}} inches}}}}
}}
| label42 = Weight
| data42 = {{Br separated entries
| 1 = {{#if:{{{weightkilograms|}}}|{{{weightkilograms|}}} kilograms}}
| 2 = {{#if:{{{weightpounds|{{{weightounces|}}}}}}|{{{weightpounds|0}}} pounds{{#if:{{{weightounces|}}}|, {{{weightounces|}}} ounces}}}}
}}
| label43 = Hair colour
| data43 = {{{haircolour|}}}
| label44 = Eye colour
| data44 = {{{eyecolour|}}}
| header45 = {{#if:{{{parents|{{{siblings|{{{spouse|{{{partner|{{{children|{{{relatives|}}}}}}}}}}}}}}}}}}|Family information}}
| label46 = Parent(s)
| data46 = {{{parents|}}}
| label47 = Sibling(s)
| data47 = {{{siblings|}}}
| label54 = Spouse(s)/partner(s)
| data54 = {{{spouse|{{{partner|}}}}}}
| label56 = Child(ren)
| data56 = {{{children|}}}
| label58 = Other family
| data58 = {{{relatives|}}}
| header59 = {{#if:{{{citizenship|{{{occupation|{{{employer|{{{affiliation|}}}}}}}}}}}}|Affiliation(s)}}
| label60 = Citizenship
| data60 = {{{citizenship|}}}
| label61 = Occupation(s)
| data61 = {{{occupation|}}}
| label62 = Employer(s)
| data62 = {{{employer|}}}
| label63 = Affiliation(s)
| data63 = {{{affiliation|}}}
}}<!--
-->{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using {{if empty|{{{template_name|}}}|character}} with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview = Page using [[Template:{{#if:{{{template_name|}}}|{{ucfirst:{{{template_name|}}}}}|Character}}]] with unknown parameter "_VALUE_"|ignoreblank=n<!--this check deliberately flags empty unknown parameters; see talk, December 2022-->
| abovestyle | affiliation | aliases | alt | birthdate | birthname | birthplace | burialdate | burialplace | caption | child | children | citizenship | currenttimeline | deathcause | deathdate | deathplace | embed | employer | ethnicity | eyecolour | fullname | gender | haircolour | heightfeet | heightinches | heightmetres | image | imagecaption | imagesize | imageupright | landscape | name | nativename | nativenamelang | nocatwdimage | occupation | originaltimeline | parents | partner | pronouns | race | relatives | residence | sex | siblings | species | spouse | title | weightkilograms | weightounces | weightpounds }}<!--
-->{{#invoke:Check for clobbered parameters|check
| nested = 1
| child; embed
| caption; imagecaption
| gender; sex
| ethnicity; race
| heightmeters; heightmetres
| haircolor; haircolour
| eyecolor; eyecolour
| partner; spouse
}}<noinclude>
{{documentation}}</noinclude>
aa69f25f0e1a71335817fa4a05e2872407371d06
Template:PAGENAMEBASE
10
20
25
2023-12-27T06:50:40Z
CreepersNeedHugs
2
Created page with "{{{{{|safesubst:}}}#Invoke:String|replace|{{{1|{{{{{|safesubst:}}}PAGENAME}}}}}|%s+%b()$||1|false}}<noinclude> {{documentation}} </noinclude>"
wikitext
text/x-wiki
{{{{{|safesubst:}}}#Invoke:String|replace|{{{1|{{{{{|safesubst:}}}PAGENAME}}}}}|%s+%b()$||1|false}}<noinclude>
{{documentation}}
</noinclude>
f23a5d434cb5b0baac5e1f58e9ceef9118e6873f
Module:String
828
21
26
2023-12-27T06:51:41Z
CreepersNeedHugs
2
Created page with "--[[ This module is intended to provide access to basic string functions. Most of the functions provided here can be invoked with named parameters, unnamed parameters, or a mixture. If named parameters are used, Mediawiki will automatically remove any leading or trailing whitespace from the parameter. Depending on the intended use, it may be advantageous to either preserve or remove such whitespace. Global options ignore_errors: If set to 'true' or 1, any error c..."
Scribunto
text/plain
--[[
This module is intended to provide access to basic string functions.
Most of the functions provided here can be invoked with named parameters,
unnamed parameters, or a mixture. If named parameters are used, Mediawiki will
automatically remove any leading or trailing whitespace from the parameter.
Depending on the intended use, it may be advantageous to either preserve or
remove such whitespace.
Global options
ignore_errors: If set to 'true' or 1, any error condition will result in
an empty string being returned rather than an error message.
error_category: If an error occurs, specifies the name of a category to
include with the error message. The default category is
[Category:Errors reported by Module String].
no_category: If set to 'true' or 1, no category will be added if an error
is generated.
Unit tests for this module are available at Module:String/tests.
]]
local str = {}
--[[
len
This function returns the length of the target string.
Usage:
{{#invoke:String|len|target_string|}}
OR
{{#invoke:String|len|s=target_string}}
Parameters
s: The string whose length to report
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string.
]]
function str.len( frame )
local new_args = str._getParameters( frame.args, {'s'} )
local s = new_args['s'] or ''
return mw.ustring.len( s )
end
--[[
sub
This function returns a substring of the target string at specified indices.
Usage:
{{#invoke:String|sub|target_string|start_index|end_index}}
OR
{{#invoke:String|sub|s=target_string|i=start_index|j=end_index}}
Parameters
s: The string to return a subset of
i: The first index of the substring to return, defaults to 1.
j: The last index of the string to return, defaults to the last character.
The first character of the string is assigned an index of 1. If either i or j
is a negative value, it is interpreted the same as selecting a character by
counting from the end of the string. Hence, a value of -1 is the same as
selecting the last character of the string.
If the requested indices are out of range for the given string, an error is
reported.
]]
function str.sub( frame )
local new_args = str._getParameters( frame.args, { 's', 'i', 'j' } )
local s = new_args['s'] or ''
local i = tonumber( new_args['i'] ) or 1
local j = tonumber( new_args['j'] ) or -1
local len = mw.ustring.len( s )
-- Convert negatives for range checking
if i < 0 then
i = len + i + 1
end
if j < 0 then
j = len + j + 1
end
if i > len or j > len or i < 1 or j < 1 then
return str._error( 'String subset index out of range' )
end
if j < i then
return str._error( 'String subset indices out of order' )
end
return mw.ustring.sub( s, i, j )
end
--[[
This function implements that features of {{str sub old}} and is kept in order
to maintain these older templates.
]]
function str.sublength( frame )
local i = tonumber( frame.args.i ) or 0
local len = tonumber( frame.args.len )
return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) )
end
--[[
_match
This function returns a substring from the source string that matches a
specified pattern. It is exported for use in other modules
Usage:
strmatch = require("Module:String")._match
sresult = strmatch( s, pattern, start, match, plain, nomatch )
Parameters
s: The string to search
pattern: The pattern or string to find within the string
start: The index within the source string to start the search. The first
character of the string has index 1. Defaults to 1.
match: In some cases it may be possible to make multiple matches on a single
string. This specifies which match to return, where the first match is
match= 1. If a negative number is specified then a match is returned
counting from the last match. Hence match = -1 is the same as requesting
the last match. Defaults to 1.
plain: A flag indicating that the pattern should be understood as plain
text. Defaults to false.
nomatch: If no match is found, output the "nomatch" value rather than an error.
For information on constructing Lua patterns, a form of [regular expression], see:
* http://www.lua.org/manual/5.1/manual.html#5.4.1
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns
]]
-- This sub-routine is exported for use in other modules
function str._match( s, pattern, start, match_index, plain_flag, nomatch )
if s == '' then
return str._error( 'Target string is empty' )
end
if pattern == '' then
return str._error( 'Pattern string is empty' )
end
start = tonumber(start) or 1
if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then
return str._error( 'Requested start is out of range' )
end
if match_index == 0 then
return str._error( 'Match index is out of range' )
end
if plain_flag then
pattern = str._escapePattern( pattern )
end
local result
if match_index == 1 then
-- Find first match is simple case
result = mw.ustring.match( s, pattern, start )
else
if start > 1 then
s = mw.ustring.sub( s, start )
end
local iterator = mw.ustring.gmatch(s, pattern)
if match_index > 0 then
-- Forward search
for w in iterator do
match_index = match_index - 1
if match_index == 0 then
result = w
break
end
end
else
-- Reverse search
local result_table = {}
local count = 1
for w in iterator do
result_table[count] = w
count = count + 1
end
result = result_table[ count + match_index ]
end
end
if result == nil then
if nomatch == nil then
return str._error( 'Match not found' )
else
return nomatch
end
else
return result
end
end
--[[
match
This function returns a substring from the source string that matches a
specified pattern.
Usage:
{{#invoke:String|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}}
OR
{{#invoke:String|match|s=source_string|pattern=pattern_string|start=start_index
|match=match_number|plain=plain_flag|nomatch=nomatch_output}}
Parameters
s: The string to search
pattern: The pattern or string to find within the string
start: The index within the source string to start the search. The first
character of the string has index 1. Defaults to 1.
match: In some cases it may be possible to make multiple matches on a single
string. This specifies which match to return, where the first match is
match= 1. If a negative number is specified then a match is returned
counting from the last match. Hence match = -1 is the same as requesting
the last match. Defaults to 1.
plain: A flag indicating that the pattern should be understood as plain
text. Defaults to false.
nomatch: If no match is found, output the "nomatch" value rather than an error.
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from each string. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
If the match_number or start_index are out of range for the string being queried, then
this function generates an error. An error is also generated if no match is found.
If one adds the parameter ignore_errors=true, then the error will be suppressed and
an empty string will be returned on any failure.
For information on constructing Lua patterns, a form of [regular expression], see:
* http://www.lua.org/manual/5.1/manual.html#5.4.1
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns
]]
-- This is the entry point for #invoke:String|match
function str.match( frame )
local new_args = str._getParameters( frame.args, {'s', 'pattern', 'start', 'match', 'plain', 'nomatch'} )
local s = new_args['s'] or ''
local start = tonumber( new_args['start'] ) or 1
local plain_flag = str._getBoolean( new_args['plain'] or false )
local pattern = new_args['pattern'] or ''
local match_index = math.floor( tonumber(new_args['match']) or 1 )
local nomatch = new_args['nomatch']
return str._match( s, pattern, start, match_index, plain_flag, nomatch )
end
--[[
pos
This function returns a single character from the target string at position pos.
Usage:
{{#invoke:String|pos|target_string|index_value}}
OR
{{#invoke:String|pos|target=target_string|pos=index_value}}
Parameters
target: The string to search
pos: The index for the character to return
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
The first character has an index value of 1.
If one requests a negative value, this function will select a character by counting backwards
from the end of the string. In other words pos = -1 is the same as asking for the last character.
A requested value of zero, or a value greater than the length of the string returns an error.
]]
function str.pos( frame )
local new_args = str._getParameters( frame.args, {'target', 'pos'} )
local target_str = new_args['target'] or ''
local pos = tonumber( new_args['pos'] ) or 0
if pos == 0 or math.abs(pos) > mw.ustring.len( target_str ) then
return str._error( 'String index out of range' )
end
return mw.ustring.sub( target_str, pos, pos )
end
--[[
str_find
This function duplicates the behavior of {{str_find}}, including all of its quirks.
This is provided in order to support existing templates, but is NOT RECOMMENDED for
new code and templates. New code is recommended to use the "find" function instead.
Returns the first index in "source" that is a match to "target". Indexing is 1-based,
and the function returns -1 if the "target" string is not present in "source".
Important Note: If the "target" string is empty / missing, this function returns a
value of "1", which is generally unexpected behavior, and must be accounted for
separatetly.
]]
function str.str_find( frame )
local new_args = str._getParameters( frame.args, {'source', 'target'} )
local source_str = new_args['source'] or ''
local target_str = new_args['target'] or ''
if target_str == '' then
return 1
end
local start = mw.ustring.find( source_str, target_str, 1, true )
if start == nil then
start = -1
end
return start
end
--[[
find
This function allows one to search for a target string or pattern within another
string.
Usage:
{{#invoke:String|find|source_str|target_string|start_index|plain_flag}}
OR
{{#invoke:String|find|source=source_str|target=target_str|start=start_index|plain=plain_flag}}
Parameters
source: The string to search
target: The string or pattern to find within source
start: The index within the source string to start the search, defaults to 1
plain: Boolean flag indicating that target should be understood as plain
text and not as a Lua style regular expression, defaults to true
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the parameter. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
This function returns the first index >= "start" where "target" can be found
within "source". Indices are 1-based. If "target" is not found, then this
function returns 0. If either "source" or "target" are missing / empty, this
function also returns 0.
This function should be safe for UTF-8 strings.
]]
function str.find( frame )
local new_args = str._getParameters( frame.args, {'source', 'target', 'start', 'plain' } )
local source_str = new_args['source'] or ''
local pattern = new_args['target'] or ''
local start_pos = tonumber(new_args['start']) or 1
local plain = new_args['plain'] or true
if source_str == '' or pattern == '' then
return 0
end
plain = str._getBoolean( plain )
local start = mw.ustring.find( source_str, pattern, start_pos, plain )
if start == nil then
start = 0
end
return start
end
--[[
replace
This function allows one to replace a target string or pattern within another
string.
Usage:
{{#invoke:String|replace|source_str|pattern_string|replace_string|replacement_count|plain_flag}}
OR
{{#invoke:String|replace|source=source_string|pattern=pattern_string|replace=replace_string|
count=replacement_count|plain=plain_flag}}
Parameters
source: The string to search
pattern: The string or pattern to find within source
replace: The replacement text
count: The number of occurences to replace, defaults to all.
plain: Boolean flag indicating that pattern should be understood as plain
text and not as a Lua style regular expression, defaults to true
]]
function str.replace( frame )
local new_args = str._getParameters( frame.args, {'source', 'pattern', 'replace', 'count', 'plain' } )
local source_str = new_args['source'] or ''
local pattern = new_args['pattern'] or ''
local replace = new_args['replace'] or ''
local count = tonumber( new_args['count'] )
local plain = new_args['plain'] or true
if source_str == '' or pattern == '' then
return source_str
end
plain = str._getBoolean( plain )
if plain then
pattern = str._escapePattern( pattern )
replace = mw.ustring.gsub( replace, "%%", "%%%%" ) --Only need to escape replacement sequences.
end
local result
if count ~= nil then
result = mw.ustring.gsub( source_str, pattern, replace, count )
else
result = mw.ustring.gsub( source_str, pattern, replace )
end
return result
end
--[[
simple function to pipe string.rep to templates.
]]
function str.rep( frame )
local repetitions = tonumber( frame.args[2] )
if not repetitions then
return str._error( 'function rep expects a number as second parameter, received "' .. ( frame.args[2] or '' ) .. '"' )
end
return string.rep( frame.args[1] or '', repetitions )
end
--[[
escapePattern
This function escapes special characters from a Lua string pattern. See [1]
for details on how patterns work.
[1] https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns
Usage:
{{#invoke:String|escapePattern|pattern_string}}
Parameters
pattern_string: The pattern string to escape.
]]
function str.escapePattern( frame )
local pattern_str = frame.args[1]
if not pattern_str then
return str._error( 'No pattern string specified' )
end
local result = str._escapePattern( pattern_str )
return result
end
--[[
count
This function counts the number of occurrences of one string in another.
]]
function str.count(frame)
local args = str._getParameters(frame.args, {'source', 'pattern', 'plain'})
local source = args.source or ''
local pattern = args.pattern or ''
local plain = str._getBoolean(args.plain or true)
if plain then
pattern = str._escapePattern(pattern)
end
local _, count = mw.ustring.gsub(source, pattern, '')
return count
end
--[[
endswith
This function determines whether a string ends with another string.
]]
function str.endswith(frame)
local args = str._getParameters(frame.args, {'source', 'pattern'})
local source = args.source or ''
local pattern = args.pattern or ''
if pattern == '' then
-- All strings end with the empty string.
return "yes"
end
if mw.ustring.sub(source, -mw.ustring.len(pattern), -1) == pattern then
return "yes"
else
return ""
end
end
--[[
join
Join all non empty arguments together; the first argument is the separator.
Usage:
{{#invoke:String|join|sep|one|two|three}}
]]
function str.join(frame)
local args = {}
local sep
for _, v in ipairs( frame.args ) do
if sep then
if v ~= '' then
table.insert(args, v)
end
else
sep = v
end
end
return table.concat( args, sep or '' )
end
--[[
Helper function that populates the argument list given that user may need to use a mix of
named and unnamed parameters. This is relevant because named parameters are not
identical to unnamed parameters due to string trimming, and when dealing with strings
we sometimes want to either preserve or remove that whitespace depending on the application.
]]
function str._getParameters( frame_args, arg_list )
local new_args = {}
local index = 1
local value
for _, arg in ipairs( arg_list ) do
value = frame_args[arg]
if value == nil then
value = frame_args[index]
index = index + 1
end
new_args[arg] = value
end
return new_args
end
--[[
Helper function to handle error messages.
]]
function str._error( error_str )
local frame = mw.getCurrentFrame()
local error_category = frame.args.error_category or 'Errors reported by Module String'
local ignore_errors = frame.args.ignore_errors or false
local no_category = frame.args.no_category or false
if str._getBoolean(ignore_errors) then
return ''
end
local error_str = '<strong class="error">String Module Error: ' .. error_str .. '</strong>'
if error_category ~= '' and not str._getBoolean( no_category ) then
error_str = '[[Category:' .. error_category .. ']]' .. error_str
end
return error_str
end
--[[
Helper Function to interpret boolean strings
]]
function str._getBoolean( boolean_str )
local boolean_value
if type( boolean_str ) == 'string' then
boolean_str = boolean_str:lower()
if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0'
or boolean_str == '' then
boolean_value = false
else
boolean_value = true
end
elseif type( boolean_str ) == 'boolean' then
boolean_value = boolean_str
else
error( 'No boolean value found' )
end
return boolean_value
end
--[[
Helper function that escapes all pattern characters so that they will be treated
as plain text.
]]
function str._escapePattern( pattern_str )
return mw.ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" )
end
return str
2ad0905c56ef4955950b75a8f00974fe82aed5e4
Module:InfoboxImage
828
22
27
2023-12-27T06:53:17Z
CreepersNeedHugs
2
Created page with "-- Inputs: -- image - Can either be a bare filename (with or without the File:/Image: prefix) or a fully formatted image link -- page - page to display for multipage images (DjVu) -- size - size to display the image -- maxsize - maximum size for image -- sizedefault - default size to display the image if size param is blank -- alt - alt text for image -- title - title text for image -- border - set to yes if border -- center - set to yes, if th..."
Scribunto
text/plain
-- Inputs:
-- image - Can either be a bare filename (with or without the File:/Image: prefix) or a fully formatted image link
-- page - page to display for multipage images (DjVu)
-- size - size to display the image
-- maxsize - maximum size for image
-- sizedefault - default size to display the image if size param is blank
-- alt - alt text for image
-- title - title text for image
-- border - set to yes if border
-- center - set to yes, if the image has to be centered
-- upright - upright image param
-- suppressplaceholder - if yes then checks to see if image is a placeholder and suppresses it
-- link - page to visit when clicking on image
-- class - HTML classes to add to the image
-- Outputs:
-- Formatted image.
-- More details available at the "Module:InfoboxImage/doc" page
local i = {};
local placeholder_image = {
"Blue - Replace this image female.svg",
"Blue - Replace this image male.svg",
"Female no free image yet.png",
"Flag of None (square).svg",
"Flag of None.svg",
"Flag of.svg",
"Green - Replace this image female.svg",
"Green - Replace this image male.svg",
"Image is needed female.svg",
"Image is needed male.svg",
"Location map of None.svg",
"Male no free image yet.png",
"Missing flag.png",
"No flag.svg",
"No free portrait.svg",
"No portrait (female).svg",
"No portrait (male).svg",
"Red - Replace this image female.svg",
"Red - Replace this image male.svg",
"Replace this image female (blue).svg",
"Replace this image female.svg",
"Replace this image male (blue).svg",
"Replace this image male.svg",
"Silver - Replace this image female.svg",
"Silver - Replace this image male.svg",
"Replace this image.svg",
"Cricket no pic.png",
"CarersLogo.gif",
"Diagram Needed.svg",
"Example.jpg",
"Image placeholder.png",
"No male portrait.svg",
"Nocover-upload.png",
"NoDVDcover copy.png",
"Noribbon.svg",
"No portrait-BFD-test.svg",
"Placeholder barnstar ribbon.png",
"Project Trains no image.png",
"Image-request.png",
"Sin bandera.svg",
"Sin escudo.svg",
"Replace this image - temple.png",
"Replace this image butterfly.png",
"Replace this image.svg",
"Replace this image1.svg",
"Resolution angle.png",
"Image-No portrait-text-BFD-test.svg",
"Insert image here.svg",
"No image available.png",
"NO IMAGE YET square.png",
"NO IMAGE YET.png",
"No Photo Available.svg",
"No Screenshot.svg",
"No-image-available.jpg",
"Null.png",
"PictureNeeded.gif",
"Place holder.jpg",
"Unbenannt.JPG",
"UploadACopyrightFreeImage.svg",
"UploadAnImage.gif",
"UploadAnImage.svg",
"UploadAnImageShort.svg",
"CarersLogo.gif",
"Diagram Needed.svg",
"No male portrait.svg",
"NoDVDcover copy.png",
"Placeholder barnstar ribbon.png",
"Project Trains no image.png",
"Image-request.png",
"Noimage.gif",
}
function i.IsPlaceholder(image)
-- change underscores to spaces
image = mw.ustring.gsub(image, "_", " ");
assert(image ~= nil, 'mw.ustring.gsub(image, "_", " ") must not return nil')
-- if image starts with [[ then remove that and anything after |
if mw.ustring.sub(image,1,2) == "[[" then
image = mw.ustring.sub(image,3);
image = mw.ustring.gsub(image, "([^|]*)|.*", "%1");
assert(image ~= nil, 'mw.ustring.gsub(image, "([^|]*)|.*", "%1") must not return nil')
end
-- Trim spaces
image = mw.ustring.gsub(image, '^[ ]*(.-)[ ]*$', '%1');
assert(image ~= nil, "mw.ustring.gsub(image, '^[ ]*(.-)[ ]*$', '%1') must not return nil")
-- remove prefix if exists
local allNames = mw.site.namespaces[6].aliases
allNames[#allNames + 1] = mw.site.namespaces[6].name
allNames[#allNames + 1] = mw.site.namespaces[6].canonicalName
for i, name in ipairs(allNames) do
if mw.ustring.lower(mw.ustring.sub(image, 1, mw.ustring.len(name) + 1)) == mw.ustring.lower(name .. ":") then
image = mw.ustring.sub(image, mw.ustring.len(name) + 2);
break
end
end
-- Trim spaces
image = mw.ustring.gsub(image, '^[ ]*(.-)[ ]*$', '%1');
-- capitalise first letter
image = mw.ustring.upper(mw.ustring.sub(image,1,1)) .. mw.ustring.sub(image,2);
for i,j in pairs(placeholder_image) do
if image == j then
return true
end
end
return false
end
function i.InfoboxImage(frame)
local image = frame.args["image"];
if image == "" or image == nil then
return "";
end
if image == " " then
return image;
end
if frame.args["suppressplaceholder"] ~= "no" then
if i.IsPlaceholder(image) == true then
return "";
end
end
if mw.ustring.lower(mw.ustring.sub(image,1,5)) == "http:" then
return "";
end
if mw.ustring.lower(mw.ustring.sub(image,1,6)) == "[http:" then
return "";
end
if mw.ustring.lower(mw.ustring.sub(image,1,7)) == "[[http:" then
return "";
end
if mw.ustring.lower(mw.ustring.sub(image,1,6)) == "https:" then
return "";
end
if mw.ustring.lower(mw.ustring.sub(image,1,7)) == "[https:" then
return "";
end
if mw.ustring.lower(mw.ustring.sub(image,1,8)) == "[[https:" then
return "";
end
if mw.ustring.sub(image,1,2) == "[[" then
-- search for thumbnail images and add to tracking cat if found
local cat = "";
if mw.title.getCurrentTitle().namespace == 0 and (mw.ustring.find(image, "|%s*thumb%s*[|%]]") or mw.ustring.find(image, "|%s*thumbnail%s*[|%]]")) then
cat = "[[Category:Pages using infoboxes with thumbnail images]]";
end
return image .. cat;
elseif mw.ustring.sub(image,1,2) == "{{" and mw.ustring.sub(image,1,3) ~= "{{{" then
return image;
elseif mw.ustring.sub(image,1,1) == "<" then
return image;
elseif mw.ustring.sub(image,1,8) == mw.ustring.char(127).."'\"`UNIQ" then
-- Found strip marker at begining, so pass don't process at all
return image;
else
local result = "";
local page = frame.args["page"];
local size = frame.args["size"];
local maxsize = frame.args["maxsize"];
local sizedefault = frame.args["sizedefault"];
local alt = frame.args["alt"];
local link = frame.args["link"];
local title = frame.args["title"];
local border = frame.args["border"];
local upright = frame.args["upright"] or "";
local thumbtime = frame.args["thumbtime"] or "";
local center = frame.args["center"];
local class = frame.args["class"];
-- remove prefix if exists
local allNames = mw.site.namespaces[6].aliases
allNames[#allNames + 1] = mw.site.namespaces[6].name
allNames[#allNames + 1] = mw.site.namespaces[6].canonicalName
for i, name in ipairs(allNames) do
if mw.ustring.lower(mw.ustring.sub(image, 1, mw.ustring.len(name) + 1)) == mw.ustring.lower(name .. ":") then
image = mw.ustring.sub(image, mw.ustring.len(name) + 2);
break
end
end
if maxsize ~= "" and maxsize ~= nil then
-- if no sizedefault then set to maxsize
if sizedefault == "" or sizedefault == nil then
sizedefault = maxsize
end
-- check to see if size bigger than maxsize
if size ~= "" and size ~= nil then
local sizenumber = tonumber(mw.ustring.match(size,"%d*")) or 0;
local maxsizenumber = tonumber(mw.ustring.match(maxsize,"%d*")) or 0;
if sizenumber>maxsizenumber and maxsizenumber>0 then
size = maxsize;
end
end
end
-- add px to size if just a number
if (tonumber(size) or 0) > 0 then
size = size .. "px";
end
-- add px to sizedefault if just a number
if (tonumber(sizedefault) or 0) > 0 then
sizedefault = sizedefault .. "px";
end
result = "[[File:" .. image;
if page ~= "" and page ~= nil then
result = result .. "|page=" .. page;
end
if size ~= "" and size ~= nil then
result = result .. "|" .. size;
elseif sizedefault ~= "" and sizedefault ~= nil then
result = result .. "|" .. sizedefault;
else
result = result .. "|frameless";
end
if center == "yes" then
result = result .. "|center"
end
if alt ~= "" and alt ~= nil then
result = result .. "|alt=" .. alt;
end
if link ~= "" and link ~= nil then
result = result .. "|link=" .. link;
end
if border == "yes" then
result = result .. "|border";
end
if upright == "yes" then
result = result .. "|upright";
elseif upright ~= "" then
result = result .. "|upright=" .. upright;
end
if thumbtime ~= "" then
result = result .. "|thumbtime=" .. thumbtime;
end
if class ~= nil and class ~= "" then
result = result .. "|class=" .. class;
end
-- if alt value is a keyword then do not use as a description
if alt == "thumbnail" or alt == "thumb" or alt == "frameless" or alt == "left" or alt == "center" or alt == "right" or alt == "upright" or alt == "border" or mw.ustring.match(alt or "", '^[0-9]*px$', 1) ~= nil then
alt = nil;
end
if title ~= "" and title ~= nil then
-- does title param contain any templatestyles? If yes then set to blank.
if mw.ustring.match(frame:preprocess(title), 'UNIQ%-%-templatestyles', 1) ~= nil then
title = nil;
end
end
if title ~= "" and title ~= nil then
result = result .. "|" .. title;
end
result = result .. "]]";
return result;
end
end
return i;
35066ee19938554ca6eeb18d6e22d2063336b7e1
Module:Check for unknown parameters
828
23
28
2023-12-27T06:54:38Z
CreepersNeedHugs
2
Created page with "-- This module may be used to compare the arguments passed to the parent -- with a list of arguments, returning a specified result if an argument is -- not on the list local p = {} local function trim(s) return s:match('^%s*(.-)%s*$') end local function isnotempty(s) return s and s:match('%S') end local function clean(text) -- Return text cleaned for display and truncated if too long. -- Strip markers are replaced with dummy text representing the original wikitext..."
Scribunto
text/plain
-- This module may be used to compare the arguments passed to the parent
-- with a list of arguments, returning a specified result if an argument is
-- not on the list
local p = {}
local function trim(s)
return s:match('^%s*(.-)%s*$')
end
local function isnotempty(s)
return s and s:match('%S')
end
local function clean(text)
-- Return text cleaned for display and truncated if too long.
-- Strip markers are replaced with dummy text representing the original wikitext.
local pos, truncated
local function truncate(text)
if truncated then
return ''
end
if mw.ustring.len(text) > 25 then
truncated = true
text = mw.ustring.sub(text, 1, 25) .. '...'
end
return mw.text.nowiki(text)
end
local parts = {}
for before, tag, remainder in text:gmatch('([^\127]*)\127[^\127]*%-(%l+)%-[^\127]*\127()') do
pos = remainder
table.insert(parts, truncate(before) .. '<' .. tag .. '>...</' .. tag .. '>')
end
table.insert(parts, truncate(text:sub(pos or 1)))
return table.concat(parts)
end
function p._check(args, pargs)
if type(args) ~= "table" or type(pargs) ~= "table" then
-- TODO: error handling
return
end
-- create the list of known args, regular expressions, and the return string
local knownargs = {}
local regexps = {}
for k, v in pairs(args) do
if type(k) == 'number' then
v = trim(v)
knownargs[v] = 1
elseif k:find('^regexp[1-9][0-9]*$') then
table.insert(regexps, '^' .. v .. '$')
end
end
-- loop over the parent args, and make sure they are on the list
local ignoreblank = isnotempty(args['ignoreblank'])
local showblankpos = isnotempty(args['showblankpositional'])
local values = {}
for k, v in pairs(pargs) do
if type(k) == 'string' and knownargs[k] == nil then
local knownflag = false
for _, regexp in ipairs(regexps) do
if mw.ustring.match(k, regexp) then
knownflag = true
break
end
end
if not knownflag and ( not ignoreblank or isnotempty(v) ) then
table.insert(values, clean(k))
end
elseif type(k) == 'number' and knownargs[tostring(k)] == nil then
local knownflag = false
for _, regexp in ipairs(regexps) do
if mw.ustring.match(tostring(k), regexp) then
knownflag = true
break
end
end
if not knownflag and ( showblankpos or isnotempty(v) ) then
table.insert(values, k .. ' = ' .. clean(v))
end
end
end
-- add results to the output tables
local res = {}
if #values > 0 then
local unknown_text = args['unknown'] or 'Found _VALUE_, '
if mw.getCurrentFrame():preprocess( "{{REVISIONID}}" ) == "" then
local preview_text = args['preview']
if isnotempty(preview_text) then
preview_text = require('Module:If preview')._warning({preview_text})
elseif preview == nil then
preview_text = unknown_text
end
unknown_text = preview_text
end
for _, v in pairs(values) do
-- Fix odd bug for | = which gets stripped to the empty string and
-- breaks category links
if v == '' then v = ' ' end
-- avoid error with v = 'example%2' ("invalid capture index")
local r = unknown_text:gsub('_VALUE_', {_VALUE_ = v})
table.insert(res, r)
end
end
return table.concat(res)
end
function p.check(frame)
local args = frame.args
local pargs = frame:getParent().args
return p._check(args, pargs)
end
return p
93db6d115d4328d2a5148bb42959105e367b663e
Module:Check for clobbered parameters
828
24
29
2023-12-27T06:56:13Z
CreepersNeedHugs
2
Created page with "local p = {} local function trim(s) return s:match('^%s*(.-)%s*$') end local function isnotempty(s) return s and s:match('%S') end function p.check(frame) local args = frame.args local pargs = frame:getParent().args local checknested = isnotempty(args['nested']) local delimiter = isnotempty(args['delimiter']) and args['delimiter'] or ';' local argpairs = {} for k, v in pairs(args) do if type(k) == 'number' then local plist = mw.text.split(v, delimiter)..."
Scribunto
text/plain
local p = {}
local function trim(s)
return s:match('^%s*(.-)%s*$')
end
local function isnotempty(s)
return s and s:match('%S')
end
function p.check(frame)
local args = frame.args
local pargs = frame:getParent().args
local checknested = isnotempty(args['nested'])
local delimiter = isnotempty(args['delimiter']) and args['delimiter'] or ';'
local argpairs = {}
for k, v in pairs(args) do
if type(k) == 'number' then
local plist = mw.text.split(v, delimiter)
local pfound = {}
local count = 0
for ii, vv in ipairs(plist) do
vv = trim(vv)
if checknested and pargs[vv] or isnotempty(pargs[vv]) then
count = count + 1
table.insert(pfound, vv)
end
end
if count > 1 then
table.insert(argpairs, pfound)
end
end
end
local warnmsg = {}
local res = ''
local cat = ''
if args['cat'] and mw.ustring.match(args['cat'],'^[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]:') then
cat = args['cat']
end
local template = args['template'] and ' in ' .. args['template'] or ''
if #argpairs > 0 then
for i, v in ipairs( argpairs ) do
table.insert(
warnmsg,
mw.ustring.format(
'Using more than one of the following parameters%s: <code>%s</code>.',
template,
table.concat(v, '</code>, <code>')
)
)
if cat ~= '' then
res = res .. '[[' .. cat .. '|' .. (v[1] == '' and ' ' or '') .. v[1] .. ']]'
end
end
end
if #warnmsg > 0 then
res = require('Module:If preview')._warning({
table.concat(warnmsg, '<br>')
}) .. res
end
return res
end
return p
2d18fb6802fa261d88a0e135ab147ab9f062acde
Template:Main other
10
25
33
2023-12-27T08:01:18Z
CreepersNeedHugs
2
Created page with "{{#switch: <!--If no or empty "demospace" parameter then detect namespace--> {{#if:{{{demospace|}}} | {{lc: {{{demospace}}} }} <!--Use lower case "demospace"--> | {{#ifeq:{{NAMESPACE}}|{{ns:0}} | main | other }} }} | main = {{{1|}}} | other | #default = {{{2|}}} }}<noinclude> {{documentation}} <!-- Add categories to the /doc subpage; interwikis go to Wikidata, thank you! --> </noinclude>"
wikitext
text/x-wiki
{{#switch:
<!--If no or empty "demospace" parameter then detect namespace-->
{{#if:{{{demospace|}}}
| {{lc: {{{demospace}}} }} <!--Use lower case "demospace"-->
| {{#ifeq:{{NAMESPACE}}|{{ns:0}}
| main
| other
}}
}}
| main = {{{1|}}}
| other
| #default = {{{2|}}}
}}<noinclude>
{{documentation}}
<!-- Add categories to the /doc subpage; interwikis go to Wikidata, thank you! -->
</noinclude>
86ad907ffeea3cc545159e00cd1f2d6433946450
Template:Template link
10
26
34
2023-12-27T08:22:54Z
CreepersNeedHugs
2
Created page with "{{[[Template:{{{1}}}|{{{1}}}]]}}<noinclude>{{documentation}} <!-- Categories go on the /doc subpage and interwikis go on Wikidata. --> </noinclude>"
wikitext
text/x-wiki
{{[[Template:{{{1}}}|{{{1}}}]]}}<noinclude>{{documentation}}
<!-- Categories go on the /doc subpage and interwikis go on Wikidata. -->
</noinclude>
eabbec62efe3044a98ebb3ce9e7d4d43c222351d
Template:Character/doc
10
27
41
2023-12-27T08:34:10Z
CreepersNeedHugs
2
Created page with ": '''NOTICE: ''The Man in the High Castle'' Wiki's Template:Character is partially or fully copied or adapted from [[w:|Wikipedia]]'s [[w:Template:Infobox person|Template:Infobox person]].''' : '''NOTICE: ''The Man in the High Castle'' Wiki's Template:Character/doc is partially or fully copied or adapted from [[w:|Wikipedia]]'s [[w:Template:Infobox person/doc|Template:Infobox person/doc]].''' {{Template link|Character}} may be used to summarize information about a parti..."
wikitext
text/x-wiki
: '''NOTICE: ''The Man in the High Castle'' Wiki's Template:Character is partially or fully copied or adapted from [[w:|Wikipedia]]'s [[w:Template:Infobox person|Template:Infobox person]].'''
: '''NOTICE: ''The Man in the High Castle'' Wiki's Template:Character/doc is partially or fully copied or adapted from [[w:|Wikipedia]]'s [[w:Template:Infobox person/doc|Template:Infobox person/doc]].'''
{{Template link|Character}} may be used to summarize information about a particular character, usually at the top of an article.
===Usage===
{{Character
| name = ''name''
| image = Frank Frink.jpeg
| caption = ''caption''
| fullname = ''fullname''
| aliases = ''aliases''
| title = ''title''
| originaltimeline = ''originaltimeline''
| currenttimeline = ''currenttimeline''
| birthdate = ''birthdate''
| birthplace = ''birthplace''
| birthname = ''birthname''
| deathdate = ''birthdate''
| deathplace = ''birthplace''
| deathcause = ''deathcause''
| residence = ''residence''
| species = ''species''
| gender = ''gender''
| pronouns = ''pronouns''
| race = ''race''
| heightmetres = ''heightmetres''
| heightfeet = ''heightfeet''
| heightinches = ''heightinches''
| weightkilograms = ''weightkilograms''
| weightpounds = ''weightpounds''
| weightounces = ''weightounces''
| haircolour = ''haircolour''
| eyecolour = ''haircolour''
| spouse = ''spouse''
| children = ''children''
| relatives = ''relatives''
| citizenship = ''citizenship''
| occupation = ''occupation''
| employer = ''employer''
| affiliation = ''affiliation''
}}
<syntaxhighlight lang="wikitext" style="overflow:auto; line-height:1.2em;">
{{Character
| name = ''name''
| image = Frank Frink.jpeg
| caption = ''caption''
| fullname = ''fullname''
| aliases = ''aliases''
| title = ''title''
| originaltimeline = ''originaltimeline''
| currenttimeline = ''currenttimeline''
| birthdate = ''birthdate''
| birthplace = ''birthplace''
| birthname = ''birthname''
| deathdate = ''birthdate''
| deathplace = ''birthplace''
| deathcause = ''deathcause''
| residence = ''residence''
| species = ''species''
| gender = ''gender''
| pronouns = ''pronouns''
| race = ''race''
| heightmetres = ''heightmetres''
| heightfeet = ''heightfeet''
| heightinches = ''heightinches''
| weightkilograms = ''weightkilograms''
| weightpounds = ''weightpounds''
| weightounces = ''weightounces''
| haircolour = ''haircolour''
| eyecolour = ''haircolour''
| spouse = ''spouse''
| children = ''children''
| relatives = ''relatives''
| citizenship = ''citizenship''
| occupation = ''occupation''
| employer = ''employer''
| affiliation = ''affiliation''
}}
</syntaxhighlight>
==Blank template==
Below is a blank version of the template to be used for copying and pasting.
<syntaxhighlight lang="wikitext" style="overflow:auto; line-height:1.2em;">
{{Character
| name =
| image =
| caption =
| fullname =
| aliases =
| title =
| originaltimeline =
| currenttimeline =
| birthdate =
| birthplace =
| birthname =
| deathdate =
| deathplace =
| deathcause =
| residence =
| species =
| gender =
| pronouns =
| race =
| heightmetres =
| heightfeet =
| heightinches =
| weightkilograms =
| weightpounds =
| weightounces =
| haircolour =
| eyecolour =
| spouse =
| children =
| relatives =
| citizenship =
| occupation =
| employer =
| affiliation =
}}
</syntaxhighlight>
57ed62c0e71e002cc18e413a98d4f6dfaff904d9
42
41
2023-12-27T08:35:18Z
CreepersNeedHugs
2
wikitext
text/x-wiki
: '''NOTICE: ''The Man in the High Castle'' Wiki's Template:Character is partially or fully copied or adapted from [[w:|Wikipedia]]'s [[w:Template:Infobox person|Template:Infobox person]].'''
: '''NOTICE: ''The Man in the High Castle'' Wiki's Template:Character/doc is partially or fully copied or adapted from [[w:|Wikipedia]]'s [[w:Template:Infobox person/doc|Template:Infobox person/doc]].'''
{{Template link|Character}} may be used to summarize information about a particular character, usually at the top of an article.
===Usage===
{{Character
| name = ''name''
| image = Frank Frink.jpeg
| caption = ''caption''
| fullname = ''fullname''
| aliases = ''aliases''
| title = ''title''
| originaltimeline = ''originaltimeline''
| currenttimeline = ''currenttimeline''
| birthdate = ''birthdate''
| birthplace = ''birthplace''
| birthname = ''birthname''
| deathdate = ''birthdate''
| deathplace = ''birthplace''
| deathcause = ''deathcause''
| residence = ''residence''
| species = ''species''
| gender = ''gender''
| pronouns = ''pronouns''
| race = ''race''
| heightmetres = ''heightmetres''
| heightfeet = ''heightfeet''
| heightinches = ''heightinches''
| weightkilograms = ''weightkilograms''
| weightpounds = ''weightpounds''
| weightounces = ''weightounces''
| haircolour = ''haircolour''
| eyecolour = ''haircolour''
| spouse = ''spouse''
| children = ''children''
| relatives = ''relatives''
| citizenship = ''citizenship''
| occupation = ''occupation''
| employer = ''employer''
| affiliation = ''affiliation''
}}
<syntaxhighlight>
{{Character
| name = ''name''
| image = Frank Frink.jpeg
| caption = ''caption''
| fullname = ''fullname''
| aliases = ''aliases''
| title = ''title''
| originaltimeline = ''originaltimeline''
| currenttimeline = ''currenttimeline''
| birthdate = ''birthdate''
| birthplace = ''birthplace''
| birthname = ''birthname''
| deathdate = ''birthdate''
| deathplace = ''birthplace''
| deathcause = ''deathcause''
| residence = ''residence''
| species = ''species''
| gender = ''gender''
| pronouns = ''pronouns''
| race = ''race''
| heightmetres = ''heightmetres''
| heightfeet = ''heightfeet''
| heightinches = ''heightinches''
| weightkilograms = ''weightkilograms''
| weightpounds = ''weightpounds''
| weightounces = ''weightounces''
| haircolour = ''haircolour''
| eyecolour = ''haircolour''
| spouse = ''spouse''
| children = ''children''
| relatives = ''relatives''
| citizenship = ''citizenship''
| occupation = ''occupation''
| employer = ''employer''
| affiliation = ''affiliation''
}}
</syntaxhighlight>
==Blank template==
Below is a blank version of the template to be used for copying and pasting.
<syntaxhighlight lang>
{{Character
| name =
| image =
| caption =
| fullname =
| aliases =
| title =
| originaltimeline =
| currenttimeline =
| birthdate =
| birthplace =
| birthname =
| deathdate =
| deathplace =
| deathcause =
| residence =
| species =
| gender =
| pronouns =
| race =
| heightmetres =
| heightfeet =
| heightinches =
| weightkilograms =
| weightpounds =
| weightounces =
| haircolour =
| eyecolour =
| spouse =
| children =
| relatives =
| citizenship =
| occupation =
| employer =
| affiliation =
}}
</syntaxhighlight>
f4292c8926178f63d4024e8dd3fb1f128c2d71b6
45
42
2023-12-27T13:27:35Z
CreepersNeedHugs
2
wikitext
text/x-wiki
: '''NOTICE: ''The Man in the High Castle'' Wiki's Template:Character is partially or fully copied or adapted from [[w:|Wikipedia]]'s [[w:Template:Infobox person|Template:Infobox person]].'''
: '''NOTICE: ''The Man in the High Castle'' Wiki's Template:Character/doc is partially or fully copied or adapted from [[w:|Wikipedia]]'s [[w:Template:Infobox person/doc|Template:Infobox person/doc]].'''
{{Template link|Character}} may be used to summarize information about a particular character, usually at the top of an article.
===Usage===
{{Character
| name = ''name''
| image = Frank Frink.jpeg
| caption = ''caption''
| fullname = ''fullname''
| aliases = ''aliases''
| title = ''title''
| originaltimeline = ''originaltimeline''
| currenttimeline = ''currenttimeline''
| birthdate = ''birthdate''
| birthplace = ''birthplace''
| birthname = ''birthname''
| deathdate = ''birthdate''
| deathplace = ''birthplace''
| deathcause = ''deathcause''
| residence = ''residence''
| species = ''species''
| gender = ''gender''
| pronouns = ''pronouns''
| race = ''race''
| heightmetres = ''heightmetres''
| heightfeet = ''heightfeet''
| heightinches = ''heightinches''
| weightkilograms = ''weightkilograms''
| weightpounds = ''weightpounds''
| weightounces = ''weightounces''
| haircolour = ''haircolour''
| eyecolour = ''haircolour''
| parents = ''parents''
| siblings = ''siblings''
| spouse = ''spouse''
| children = ''children''
| relatives = ''relatives''
| citizenship = ''citizenship''
| occupation = ''occupation''
| employer = ''employer''
| affiliation = ''affiliation''
}}
<syntaxhighlight>
{{Character
| name = ''name''
| image = Frank Frink.jpeg
| caption = ''caption''
| fullname = ''fullname''
| aliases = ''aliases''
| title = ''title''
| originaltimeline = ''originaltimeline''
| currenttimeline = ''currenttimeline''
| birthdate = ''birthdate''
| birthplace = ''birthplace''
| birthname = ''birthname''
| deathdate = ''birthdate''
| deathplace = ''birthplace''
| deathcause = ''deathcause''
| residence = ''residence''
| species = ''species''
| gender = ''gender''
| pronouns = ''pronouns''
| race = ''race''
| heightmetres = ''heightmetres''
| heightfeet = ''heightfeet''
| heightinches = ''heightinches''
| weightkilograms = ''weightkilograms''
| weightpounds = ''weightpounds''
| weightounces = ''weightounces''
| haircolour = ''haircolour''
| eyecolour = ''haircolour''
| parents = ''parents''
| siblings = ''siblings''
| spouse = ''spouse''
| children = ''children''
| relatives = ''relatives''
| citizenship = ''citizenship''
| occupation = ''occupation''
| employer = ''employer''
| affiliation = ''affiliation''
}}
</syntaxhighlight>
==Blank template==
Below is a blank version of the template to be used for copying and pasting.
<syntaxhighlight lang>
{{Character
| name =
| image =
| caption =
| fullname =
| aliases =
| title =
| originaltimeline =
| currenttimeline =
| birthdate =
| birthplace =
| birthname =
| deathdate =
| deathplace =
| deathcause =
| residence =
| species =
| gender =
| pronouns =
| race =
| heightmetres =
| heightfeet =
| heightinches =
| weightkilograms =
| weightpounds =
| weightounces =
| haircolour =
| eyecolour =
| parents =
| siblings =
| spouse =
| children =
| relatives =
| citizenship =
| occupation =
| employer =
| affiliation =
}}
</syntaxhighlight>
b22ec4ff301be09626419d4a2afbc7489dd32195
Module:File link
828
28
43
2023-12-27T08:44:17Z
CreepersNeedHugs
2
Created page with "-- This module provides a library for formatting file wikilinks. local yesno = require('Module:Yesno') local checkType = require('libraryUtil').checkType local p = {} function p._main(args) checkType('_main', 1, args, 'table') -- This is basically libraryUtil.checkTypeForNamedArg, but we are rolling our -- own function to get the right error level. local function checkArg(key, val, level) if type(val) ~= 'string' then error(string.format( "type error in..."
Scribunto
text/plain
-- This module provides a library for formatting file wikilinks.
local yesno = require('Module:Yesno')
local checkType = require('libraryUtil').checkType
local p = {}
function p._main(args)
checkType('_main', 1, args, 'table')
-- This is basically libraryUtil.checkTypeForNamedArg, but we are rolling our
-- own function to get the right error level.
local function checkArg(key, val, level)
if type(val) ~= 'string' then
error(string.format(
"type error in '%s' parameter of '_main' (expected string, got %s)",
key, type(val)
), level)
end
end
local ret = {}
-- Adds a positional parameter to the buffer.
local function addPositional(key)
local val = args[key]
if not val then
return nil
end
checkArg(key, val, 4)
ret[#ret + 1] = val
end
-- Adds a named parameter to the buffer. We assume that the parameter name
-- is the same as the argument key.
local function addNamed(key)
local val = args[key]
if not val then
return nil
end
checkArg(key, val, 4)
ret[#ret + 1] = key .. '=' .. val
end
-- Filename
checkArg('file', args.file, 3)
ret[#ret + 1] = 'File:' .. args.file
-- Format
if args.format then
checkArg('format', args.format)
if args.formatfile then
checkArg('formatfile', args.formatfile)
ret[#ret + 1] = args.format .. '=' .. args.formatfile
else
ret[#ret + 1] = args.format
end
end
-- Border
if yesno(args.border) then
ret[#ret + 1] = 'border'
end
addPositional('location')
addPositional('alignment')
addPositional('size')
addNamed('upright')
addNamed('link')
addNamed('alt')
addNamed('page')
addNamed('class')
addNamed('lang')
addNamed('start')
addNamed('end')
addNamed('thumbtime')
addPositional('caption')
return string.format('[[%s]]', table.concat(ret, '|'))
end
function p.main(frame)
local origArgs = require('Module:Arguments').getArgs(frame, {
wrappers = 'Template:File link'
})
if not origArgs.file then
error("'file' parameter missing from [[Template:File link]]", 0)
end
-- Copy the arguments that were passed to a new table to avoid looking up
-- every possible parameter in the frame object.
local args = {}
for k, v in pairs(origArgs) do
-- Make _BLANK a special argument to add a blank parameter. For use in
-- conditional templates etc. it is useful for blank arguments to be
-- ignored, but we still need a way to specify them so that we can do
-- things like [[File:Example.png|link=]].
if v == '_BLANK' then
v = ''
end
args[k] = v
end
return p._main(args)
end
return p
66925f088d11530f2482f04181a3baaaa0ad3d0c
Joe Blake
0
29
44
2023-12-27T13:13:19Z
CreepersNeedHugs
2
Created page with "There are several versions of '''Joe Blake''' in ''The Man in the High Castle''. *The '''[[Joe Blake/television series|Joe Blake]]''' in the television series. *The '''[[Joe Blake/novel|Joe Blake]]''' in the novel."
wikitext
text/x-wiki
There are several versions of '''Joe Blake''' in ''The Man in the High Castle''.
*The '''[[Joe Blake/television series|Joe Blake]]''' in the television series.
*The '''[[Joe Blake/novel|Joe Blake]]''' in the novel.
bd90e8be8b556219d4855783e4bc43699d0059aa
Joe Blake/television series/main timeline
0
30
46
2023-12-27T13:42:03Z
CreepersNeedHugs
2
Created page with "{{Character | name = Joe Blake | image = | caption = | fullname = Joseph Blake | aliases = | title = | originaltimeline = [[Main timeline]] | currenttimeline = [[Main timeline]] | birthdate = 10 April, 1935 | birthplace = | birthname = Josef Heusmann | deathdate = | deathplace = | deathcause = | residence = [[New York City]], [[American Reich]..."
wikitext
text/x-wiki
{{Character
| name = Joe Blake
| image =
| caption =
| fullname = Joseph Blake
| aliases =
| title =
| originaltimeline = [[Main timeline]]
| currenttimeline = [[Main timeline]]
| birthdate = 10 April, 1935
| birthplace =
| birthname = Josef Heusmann
| deathdate =
| deathplace =
| deathcause =
| residence = [[New York City]], [[American Reich]]
| species = Human
| gender = Male
| pronouns =
| race = White <small>(Aryan)</small>
| heightmetres =
| heightfeet =
| heightinches =
| weightkilograms =
| weightpounds =
| weightounces =
| haircolour =
| eyecolour =
| parents = *[[Elsa]] <small>(mother)</small>
*[[Martin Heusmann]] <small>(father)</small>
*[[Heinrich Himmler]] <small>(godfather)</small>
*[[Gerda Heusmann]] <small>(step-mother)</small>
| spouse =
| children = *[[Dieter Heusmann]] <small>(half-brother)</small>
*[[Olaf Heusmann]] <small>(half-brother)</small>
| relatives = [[Ernst Heusmann]] <small>(paternal ancestor)</small>
| citizenship = American Reich
| occupation = ''Schutzstaffel'' agent
| employer = ''[[Schutzstaffel]]''
| affiliation = *[[American Resistance]] <small>(spy)</small>
**[[East Coast Resistance]] <small>(spy)</small>
}}
'''Joe Blake''' was a male undercover operative of the ''[[Schutzstaffel]]''.
==Biography==
''To be added''
==Appearances==
===Season One===
*Episode 1: "[[The New World]]"
*''More'' (to be added)
[[Category:Characters]]
[[Category:Citizens of the American Reich]]
[[Category:Heusmann family]]
[[Category:Males]]
[[Category:Schutzstaffel agents]]
ecc31af40ef768630a496e371357254186ebf451
Juliana Crain
0
31
47
2023-12-27T14:01:27Z
CreepersNeedHugs
2
Created page with "There are several versions of '''Juliana Crain''' in ''The Man in the High Castle'''. *The '''[[Juliana Crain/television series/main timeline|Juliana Crain]]''' from the [[main timeline/television series|main timeline]] in the [[The Man in the High Castle (television series)|television series]]. *The '''[[Juliana Crain/television series/Trudy lives|Juliana Crain]]''' from [[Truey lives timeline|the timeline]] where Trudy Walker/television series/main timeline|Trudy Wa..."
wikitext
text/x-wiki
There are several versions of '''Juliana Crain''' in ''The Man in the High Castle'''.
*The '''[[Juliana Crain/television series/main timeline|Juliana Crain]]''' from the [[main timeline/television series|main timeline]] in the [[The Man in the High Castle (television series)|television series]].
*The '''[[Juliana Crain/television series/Trudy lives|Juliana Crain]]''' from [[Truey lives timeline|the timeline]] where [[Trudy Walker/television series/main timeline|Trudy Walker]] lives in the television series.
*The '''[[Juliana Crain/television series/Cuban Missile Crisis|Juliana Crain]]''' from the timeline where the [[Cuban Missile Crisis]] occurs in the television series.
*The '''[[Juliana Crain/novel]]''' in the [[The Man in the High Castle (novel)|novel]].
6c450106e7f290bfb14bbeb99e74aab321f2a2d6
48
47
2023-12-27T14:01:46Z
CreepersNeedHugs
2
wikitext
text/x-wiki
There are several versions of '''Juliana Crain''' in ''The Man in the High Castle'''.
*The '''[[Juliana Crain/television series/main timeline|Juliana Crain]]''' from the [[main timeline/television series|main timeline]] in the [[The Man in the High Castle (television series)|television series]].
*The '''[[Juliana Crain/television series/Trudy lives|Juliana Crain]]''' from [[Truey lives timeline|the timeline]] where [[Trudy Walker/television series/main timeline|Trudy Walker]] lives in the television series.
*The '''[[Juliana Crain/television series/Cuban Missile Crisis|Juliana Crain]]''' from the timeline where the [[Cuban Missile Crisis]] occurs in the television series.
*The '''[[Juliana Crain/novel|Juliana Crain]]''' in the [[The Man in the High Castle (novel)|novel]].
ebf1fbef0c24d6cc8c25ff9d241fff1e4dfbdf7c
49
48
2023-12-27T14:02:33Z
CreepersNeedHugs
2
wikitext
text/x-wiki
There are several versions of '''Juliana Crain''' in ''The Man in the High Castle'''.
*The '''[[Juliana Crain/television series/main timeline|Juliana Crain]]''' from the [[main timeline/television series|main timeline]] in the [[The Man in the High Castle (television series)|television series]].
*The '''[[Juliana Crain/television series/Trudy lives|Juliana Crain]]''' from [[Truey lives timeline|the timeline]] where [[Trudy Walker/television series/main timeline|Trudy Walker]] lives in the television series.
*The '''[[Juliana Crain/television series/Cuban Missile Crisis|Juliana Crain]]''' from [[Cuban Missile Crisis timeline|the timeline]] where the [[Cuban Missile Crisis]] occurs in the television series.
*The '''[[Juliana Crain/novel|Juliana Crain]]''' in the [[The Man in the High Castle (novel)|novel]].
31c4f57bd4d2e95601261f7b9dea0998eff9613a
Juliana Crain/television series/main timeline
0
32
50
2023-12-27T14:12:57Z
CreepersNeedHugs
2
Created page with "{{Character | name = Juliana Crain | image = | caption = | fullname = Juliana Crain | aliases = Julia Mills | title = | originaltimeline = [[Main timeline]] | currenttimeline = [[Main timeline]] | birthdate = | birthplace = | birthname = | deathdate = | deathplace = | deathcause = | residence = [[San Francisco]], [[Japanese Pacific States]]<r..."
wikitext
text/x-wiki
{{Character
| name = Juliana Crain
| image =
| caption =
| fullname = Juliana Crain
| aliases = Julia Mills
| title =
| originaltimeline = [[Main timeline]]
| currenttimeline = [[Main timeline]]
| birthdate =
| birthplace =
| birthname =
| deathdate =
| deathplace =
| deathcause =
| residence = [[San Francisco]], [[Japanese Pacific States]]<ref name="S1 E1">Season 1 Episode 1: "[[The New World]]"</ref>
| species = Human
| gender = Female
| pronouns =
| race = *White
*Gaijin
*Aryan
| heightmetres =
| heightfeet =
| heightinches =
| weightkilograms =
| weightpounds =
| weightounces =
| haircolour =
| eyecolour =
| parents = *[[Anne Walker]] <small>(mother)</small>
*[[John Crain]] <small>(father)</small>
*[[Arnold Walker]] <small>(step-father)</small>
| siblings = [[Trudy Walker]] <small>(half-sister)</small>
| spouse = [[Frank Frink]] <small>(ex-boyfriend)</small>
| children =
| relatives =
| citizenship = *[[Japanese Pacific States]]
*[[American Reich]]
| occupation =
| employer =
| affiliation = [[American Resistance]]
}}
'''Juliana Crain''' is a female operative of the [[American Resistance]].
abffd66704fae1d0d027fe44d9a1a8ac0643898a
Juliana Crain/television series/main timeline
0
32
51
50
2023-12-27T14:17:18Z
CreepersNeedHugs
2
wikitext
text/x-wiki
{{Character
| name = Juliana Crain
| image =
| caption =
| fullname = Juliana Crain
| aliases = Julia Mills
| title =
| originaltimeline = [[Main timeline]]
| currenttimeline = [[Main timeline]]
| birthdate =
| birthplace =
| birthname =
| deathdate =
| deathplace =
| deathcause =
| residence = [[San Francisco]], [[Japanese Pacific States]]<ref name="S1 E1">Season 1 Episode 1: "[[The New World]]"</ref>
| species = Human
| gender = Female
| pronouns =
| race = *White
*Gaijin
*Aryan
| heightmetres =
| heightfeet =
| heightinches =
| weightkilograms =
| weightpounds =
| weightounces =
| haircolour =
| eyecolour =
| parents = *[[Anne Walker]] <small>(mother)</small>
*[[John Crain]] <small>(father)</small>
*[[Arnold Walker]] <small>(step-father)</small>
| siblings = [[Trudy Walker]] <small>(half-sister)</small>
| spouse = [[Frank Frink]] <small>(ex-boyfriend)</small>
| children =
| relatives =
| citizenship = *[[Japanese Pacific States]]
*[[American Reich]]
| occupation =
| employer =
| affiliation = [[American Resistance]]
}}
'''Juliana Crain''' is a female operative of the [[American Resistance]].
==Biography==
''To be added''
==Appearances==
===Season One===
*Episode 1: "[[The New World]]"
*''More (to be added)''
==Notes and references==
<references/>
{{DEFAULTSORT:Crain, Juliana}}
[[Category:Crain-Walker family]]
[[Category:American Resistance members]]
[[Category:Citizens of the American Reich]]
[[Category:Citizens of the Japanese Pacific States]]
[[Category:Females]]
554b2ee81cacc5046f7745f7edd7665b2e430b1b
56
51
2023-12-27T14:29:35Z
CreepersNeedHugs
2
wikitext
text/x-wiki
{{Character
| name = Juliana Crain
| image =
| caption =
| fullname = Juliana Crain
| aliases = Julia Mills
| title =
| originaltimeline = [[Main timeline]]
| currenttimeline = [[Main timeline]]
| birthdate =
| birthplace =
| birthname =
| deathdate =
| deathplace =
| deathcause =
| residence = *[[San Francisco/main timeline|San Francisco]], [[Japanese Pacific States/main timeline|Japanese Pacific States]]<ref name="S1 E1">Season 1 Episode 1: "[[The New World]]"</ref> <small>(formerly)</small>
*[[New York City/main timeline|New York City]], [[American Reich/main timeline|American Reich]] <small>(formerly)</small>
*[[Denver/main tineline|Denver]], [[Neutral Zone/main timeline|Neutral Zone]]
| species = Human
| gender = Female
| pronouns =
| race = *White
*Gaijin
*Aryan
| heightmetres =
| heightfeet =
| heightinches =
| weightkilograms =
| weightpounds =
| weightounces =
| haircolour =
| eyecolour =
| parents = *[[Anne Walker]] <small>(mother)</small>
*[[John Crain]] <small>(father)</small>
*[[Arnold Walker]] <small>(step-father)</small>
| siblings = [[Trudy Walker/main timeline|Trudy Walker]] <small>(half-sister)</small>
| spouse = [[Frank Frink]] <small>(ex-boyfriend)</small>
| children =
| relatives =
| citizenship = *[[Japanese Pacific States/main timeline|Japanese Pacific States]]
*[[American Reich/main timeline|American Reich]]
| occupation =
| employer =
| affiliation = [[American Resistance/main timeline|American Resistance]]
}}
'''Juliana Crain''' is a female operative of the [[American Resistance/main timeline|American Resistance]].
==Biography==
''To be added''
==Appearances==
===Season One===
*Episode 1: "[[The New World]]"
*''More (to be added)''
==Notes and references==
<references/>
{{DEFAULTSORT:Crain, Juliana}}
[[Category:Crain-Walker family]]
[[Category:American Resistance members]]
[[Category:Citizens of the American Reich]]
[[Category:Citizens of the Japanese Pacific States]]
[[Category:Females]]
96dcaa08c2cc427b1a6b4f088d75f4cd728c1892
58
56
2023-12-28T00:27:01Z
CreepersNeedHugs
2
wikitext
text/x-wiki
{{Character
| name = Juliana Crain
| image =
| caption =
| fullname = Juliana Crain
| aliases = Julia Mills
| title =
| originaltimeline = [[Main timeline]]
| currenttimeline = [[Main timeline]]
| birthdate =
| birthplace =
| birthname =
| deathdate =
| deathplace =
| deathcause =
| residence = *[[San Francisco/main timeline|San Francisco]], [[Japanese Pacific States/main timeline|Japanese Pacific States]]<ref name="S1 E1">Season 1 Episode 1: "[[The New World]]"</ref> <small>(formerly)</small>
*[[New York City/main timeline|New York City]], [[American Reich/main timeline|American Reich]] <small>(formerly)</small>
*[[Denver/main tineline|Denver]], [[Colorado/main timeline|Colorado]], [[Neutral Zone/main timeline|Neutral Zone]]
| species = Human
| gender = Female
| pronouns =
| race = *White
*Gaijin
*Aryan
| heightmetres =
| heightfeet =
| heightinches =
| weightkilograms =
| weightpounds =
| weightounces =
| haircolour =
| eyecolour =
| parents = *[[Anne Walker]] <small>(mother)</small>
*[[John Crain]] <small>(father)</small>
*[[Arnold Walker]] <small>(step-father)</small>
| siblings = [[Trudy Walker/main timeline|Trudy Walker]] <small>(half-sister)</small>
| spouse = [[Frank Frink]] <small>(ex-boyfriend)</small>
| children =
| relatives =
| citizenship = *[[Japanese Pacific States/main timeline|Japanese Pacific States]]
*[[American Reich/main timeline|American Reich]]
| occupation =
| employer =
| affiliation = [[American Resistance/main timeline|American Resistance]]
}}
'''Juliana Crain''' is a female operative of the [[American Resistance/main timeline|American Resistance]].
==Biography==
''To be added''
==Appearances==
===Season One===
*Episode 1: "[[The New World]]"
*''More (to be added)''
==Notes and references==
<references/>
{{DEFAULTSORT:Crain, Juliana}}
[[Category:Crain-Walker family]]
[[Category:American Resistance members]]
[[Category:Citizens of the American Reich]]
[[Category:Citizens of the Japanese Pacific States]]
[[Category:Females]]
bc2e3736486a365b2613c8ee8d4298e87b950b29
63
58
2023-12-28T00:34:55Z
CreepersNeedHugs
2
wikitext
text/x-wiki
{{Character
| name = Juliana Crain
| image =
| caption =
| fullname = Juliana Crain
| aliases = Julia Mills
| title =
| originaltimeline = [[Main timeline]]
| currenttimeline = [[Main timeline]]
| birthdate =
| birthplace =
| birthname =
| deathdate =
| deathplace =
| deathcause =
| residence = *[[San Francisco/television series/main timeline|San Francisco]], [[Japanese Pacific States/television series/main timeline|Japanese Pacific States]]<ref name="S1 E1">Season 1 Episode 1: "[[The New World]]"</ref> <small>(formerly)</small>
*[[New York City/television series/main timeline|New York City]], [[American Reich/television series/main timeline|American Reich]] <small>(formerly)</small>
*[[Denver/television series/main tineline|Denver]], [[Colorado/television series/main timeline|Colorado]], [[Neutral Zone/television series/main timeline|Neutral Zone]]
| species = Human
| gender = Female
| pronouns =
| race = *White
*Gaijin
*Aryan
| heightmetres =
| heightfeet =
| heightinches =
| weightkilograms =
| weightpounds =
| weightounces =
| haircolour =
| eyecolour =
| parents = *[[Anne Walker]] <small>(mother)</small>
*[[John Crain]] <small>(father)</small>
*[[Arnold Walker]] <small>(step-father)</small>
| siblings = [[Trudy Walker/television series/main timeline|Trudy Walker]] <small>(half-sister)</small>
| spouse = [[Frank Frink/television series/main timeline|Frank Frink]] <small>(ex-boyfriend)</small>
| children =
| relatives =
| citizenship = *[[Japanese Pacific States/television series/main timeline|Japanese Pacific States]]
*[[American Reich/television series/main timeline|American Reich]]
| occupation =
| employer =
| affiliation = [[American Resistance/television series/main timeline|American Resistance]]
}}
'''Juliana Crain''' is a female operative of the [[American Resistance/television series/main timeline|American Resistance]].
==Biography==
''To be added''
==Appearances==
===Season One===
*Episode 1: "[[The New World]]"
*''More (to be added)''
==Notes and references==
<references/>
{{DEFAULTSORT:Crain, Juliana}}
[[Category:Crain-Walker family]]
[[Category:American Resistance members]]
[[Category:Citizens of the American Reich]]
[[Category:Citizens of the Japanese Pacific States]]
[[Category:Females]]
ba1417a42cf87db20d5597673f365e61f0ea97f3
Joe Blake/television series/main timeline
0
30
52
46
2023-12-27T14:18:20Z
CreepersNeedHugs
2
CreepersNeedHugs moved page [[Joe Blake/television series]] to [[Joe Blake/television series/main timeline]]
wikitext
text/x-wiki
{{Character
| name = Joe Blake
| image =
| caption =
| fullname = Joseph Blake
| aliases =
| title =
| originaltimeline = [[Main timeline]]
| currenttimeline = [[Main timeline]]
| birthdate = 10 April, 1935
| birthplace =
| birthname = Josef Heusmann
| deathdate =
| deathplace =
| deathcause =
| residence = [[New York City]], [[American Reich]]
| species = Human
| gender = Male
| pronouns =
| race = White <small>(Aryan)</small>
| heightmetres =
| heightfeet =
| heightinches =
| weightkilograms =
| weightpounds =
| weightounces =
| haircolour =
| eyecolour =
| parents = *[[Elsa]] <small>(mother)</small>
*[[Martin Heusmann]] <small>(father)</small>
*[[Heinrich Himmler]] <small>(godfather)</small>
*[[Gerda Heusmann]] <small>(step-mother)</small>
| spouse =
| children = *[[Dieter Heusmann]] <small>(half-brother)</small>
*[[Olaf Heusmann]] <small>(half-brother)</small>
| relatives = [[Ernst Heusmann]] <small>(paternal ancestor)</small>
| citizenship = American Reich
| occupation = ''Schutzstaffel'' agent
| employer = ''[[Schutzstaffel]]''
| affiliation = *[[American Resistance]] <small>(spy)</small>
**[[East Coast Resistance]] <small>(spy)</small>
}}
'''Joe Blake''' was a male undercover operative of the ''[[Schutzstaffel]]''.
==Biography==
''To be added''
==Appearances==
===Season One===
*Episode 1: "[[The New World]]"
*''More'' (to be added)
[[Category:Characters]]
[[Category:Citizens of the American Reich]]
[[Category:Heusmann family]]
[[Category:Males]]
[[Category:Schutzstaffel agents]]
ecc31af40ef768630a496e371357254186ebf451
55
52
2023-12-27T14:24:02Z
CreepersNeedHugs
2
wikitext
text/x-wiki
{{Character
| name = Joe Blake
| image =
| caption =
| fullname = Joseph Blake
| aliases =
| title =
| originaltimeline = [[Main timeline]]
| currenttimeline = [[Main timeline]]
| birthdate = 10 April, 1935
| birthplace =
| birthname = Josef Heusmann
| deathdate =
| deathplace =
| deathcause =
| residence = [[New York City/Main timeline|New York City]], [[American Reich/Main timeline|American Reich]]
| species = Human
| gender = Male
| pronouns =
| race = *White
*Aryan
| heightmetres =
| heightfeet =
| heightinches =
| weightkilograms =
| weightpounds =
| weightounces =
| haircolour =
| eyecolour =
| parents = *[[Elsa]] <small>(mother)</small>
*[[Martin Heusmann]] <small>(father)</small>
*[[Heinrich Himmler]] <small>(godfather)</small>
*[[Gerda Heusmann]] <small>(step-mother)</small>
| spouse =
| children = *[[Dieter Heusmann]] <small>(half-brother)</small>
*[[Olaf Heusmann]] <small>(half-brother)</small>
| relatives = [[Ernst Heusmann]] <small>(paternal ancestor)</small>
| citizenship = American Reich
| occupation = ''Schutzstaffel'' agent
| employer = ''[[Schutzstaffel]]''
| affiliation = *[[American Resistance]] <small>(spy)</small>
**[[East Coast Resistance]] <small>(spy)</small>
}}
'''Joe Blake''' was a male undercover operative of the ''[[Schutzstaffel]]''.
==Biography==
''To be added''
==Appearances==
===Season One===
*Episode 1: "[[The New World]]"
*''More'' (to be added)
[[Category:Characters]]
[[Category:Citizens of the American Reich]]
[[Category:Heusmann family]]
[[Category:Males]]
[[Category:Schutzstaffel agents]]
a6be9d7da480d067d37dc05af8eae92205f9bd7e
57
55
2023-12-27T14:30:46Z
CreepersNeedHugs
2
wikitext
text/x-wiki
{{Character
| name = Joe Blake
| image =
| caption =
| fullname = Joseph Blake
| aliases =
| title =
| originaltimeline = [[Main timeline]]
| currenttimeline = [[Main timeline]]
| birthdate = 10 April, 1935
| birthplace =
| birthname = Josef Heusmann
| deathdate =
| deathplace =
| deathcause =
| residence = [[New York City/main timeline|New York City]], [[American Reich/main timeline|American Reich]]
| species = Human
| gender = Male
| pronouns =
| race = *White
*Aryan
| heightmetres =
| heightfeet =
| heightinches =
| weightkilograms =
| weightpounds =
| weightounces =
| haircolour =
| eyecolour =
| parents = *[[Elsa]] <small>(mother)</small>
*[[Martin Heusmann]] <small>(father)</small>
*[[Heinrich Himmler]] <small>(godfather)</small>
*[[Gerda Heusmann]] <small>(step-mother)</small>
| spouse =
| children = *[[Dieter Heusmann]] <small>(half-brother)</small>
*[[Olaf Heusmann]] <small>(half-brother)</small>
| relatives = [[Ernst Heusmann]] <small>(paternal ancestor)</small>
| citizenship = American Reich
| occupation = ''Schutzstaffel'' agent
| employer = ''[[Schutzstaffel]]''
| affiliation = *[[American Resistance/main timeline|American Resistance]] <small>(spy)</small>
**[[East Coast Resistance]] <small>(spy)</small>
}}
'''Joe Blake''' was a male undercover operative of the ''[[Schutzstaffel]]''.
==Biography==
''To be added''
==Appearances==
===Season One===
*Episode 1: "[[The New World]]"
*''More'' (to be added)
[[Category:Characters]]
[[Category:Citizens of the American Reich]]
[[Category:Heusmann family]]
[[Category:Males]]
[[Category:Schutzstaffel agents]]
6694639cb0148835f593b704826d99adae0ec081
Joe Blake
0
29
54
44
2023-12-27T14:22:13Z
CreepersNeedHugs
2
wikitext
text/x-wiki
There are several versions of '''Joe Blake''' in ''The Man in the High Castle''.
*The '''[[Joe Blake/television series/main timeline|Joe Blake]]''' from the [[main timeline]] in the [[The Man in the High Castle|television series]].
*The '''[[Joe Blake/television series/San Francisco destroyed|Joe Blake]]''' from [[San Francisco destroyed timeline|the timeline]] where [[San Francisco/San Francisco destroyed|San Francisco]] is destroyed in the television series.
*The '''[[Joe Blake/novel|Joe Blake]]''' in the novel.
3bd8e155bc32b6ef793c2c8a9c98ced0046662ce
Neutral Zone/television series/main timeline
0
34
59
2023-12-28T00:32:03Z
CreepersNeedHugs
2
Created page with "The '''Neutral Zone''', also known simply as the '''NZ''',<ref name="S3 E2">Season 3 Episode 2: "[[Imagine Manchuria]]"</ref> is the buffer zone between the [[Japanese Pacific States/television series/main timeline|Japanese Pacific States]] and the [[American Reich/television series/main timeline|American Reich]]. It contains, among others, the former [[United States of America/television series/main timeline|U.S.]] state of Colorado/television series/main timeline|Col..."
wikitext
text/x-wiki
The '''Neutral Zone''', also known simply as the '''NZ''',<ref name="S3 E2">Season 3 Episode 2: "[[Imagine Manchuria]]"</ref> is the buffer zone between the [[Japanese Pacific States/television series/main timeline|Japanese Pacific States]] and the [[American Reich/television series/main timeline|American Reich]]. It contains, among others, the former [[United States of America/television series/main timeline|U.S.]] state of [[Colorado/television series/main timeline|Colorado]].
==History==
''To be added''
[[Category:Countries]]
[[Category:Locations]]
bde207ec1108a1c231de798ac4c47d430abf871a
60
59
2023-12-28T00:32:46Z
CreepersNeedHugs
2
wikitext
text/x-wiki
The '''Neutral Zone''', also known simply as the '''NZ''',<ref name="S3 E2">Season 3 Episode 2: "[[Imagine Manchuria]]"</ref> is the buffer zone between the [[Japanese Pacific States/television series/main timeline|Japanese Pacific States]] and the [[American Reich/television series/main timeline|American Reich]]. It contains, among others, the former [[United States of America/television series/main timeline|U.S.]] state of [[Colorado/television series/main timeline|Colorado]].
==History==
''To be added''
==Notes and references==
<references/>
[[Category:Countries]]
[[Category:Locations]]
c8c65dedf39185eeb76da6f19daa405e1f0a3fda
61
60
2023-12-28T00:33:10Z
CreepersNeedHugs
2
CreepersNeedHugs moved page [[Neutral Zone/main timeline]] to [[Neutral Zone/television series/main timeline]]
wikitext
text/x-wiki
The '''Neutral Zone''', also known simply as the '''NZ''',<ref name="S3 E2">Season 3 Episode 2: "[[Imagine Manchuria]]"</ref> is the buffer zone between the [[Japanese Pacific States/television series/main timeline|Japanese Pacific States]] and the [[American Reich/television series/main timeline|American Reich]]. It contains, among others, the former [[United States of America/television series/main timeline|U.S.]] state of [[Colorado/television series/main timeline|Colorado]].
==History==
''To be added''
==Notes and references==
<references/>
[[Category:Countries]]
[[Category:Locations]]
c8c65dedf39185eeb76da6f19daa405e1f0a3fda
64
61
2023-12-28T00:43:38Z
CreepersNeedHugs
2
wikitext
text/x-wiki
The '''Neutral Zone''', also known simply as the '''NZ'''<ref name="S3 E2">Season 3 Episode 2: "[[Imagine Manchuria]]"</ref> or the '''Zone''',<ref name="S3 E2"/> is the buffer zone between the [[Japanese Pacific States/television series/main timeline|Japanese Pacific States]] and the [[American Reich/television series/main timeline|American Reich]]. It contains, among others, the former [[United States of America/television series/main timeline|U.S.]] state of [[Colorado/television series/main timeline|Colorado]].
==History==
''To be added''
==Notes and references==
<references/>
[[Category:Countries]]
[[Category:Locations]]
4ca04abec9fd11802dcc747257efc94faabfaf6b
Frank Frink
0
36
65
2023-12-28T00:59:26Z
CreepersNeedHugs
2
Created page with "There are several versions of '''Frank Frink''' in ''The Man in the High Castle''. *The '''[[Frank Frink/television series/main timeline|Frank Frink]]''' from the [[main timeline/television series|main timeline]] in the television series. *The '''[[Frank Frink/television series/San Francisco destroyed|Frank Frink]]''' from [[San Francisco destroyed timeline|the timeline]] where [[San Francisco/San Francisco destroyed|San Francisco]] is destroyed in the television series..."
wikitext
text/x-wiki
There are several versions of '''Frank Frink''' in ''The Man in the High Castle''.
*The '''[[Frank Frink/television series/main timeline|Frank Frink]]''' from the [[main timeline/television series|main timeline]] in the television series.
*The '''[[Frank Frink/television series/San Francisco destroyed|Frank Frink]]''' from [[San Francisco destroyed timeline|the timeline]] where [[San Francisco/San Francisco destroyed|San Francisco]] is destroyed in the television series.
*The '''[[Frank Frink/novel|Frank Frink]]''' in the novel.
beaf6b3629a229f1603d9262f0210df2ae6dbfd3
Frank Frink/television series/main timeline
0
37
66
2023-12-28T01:14:25Z
CreepersNeedHugs
2
Created page with "{{Character | name = Frank Frink | image = | caption = | fullname = Frank Frink | aliases = | title = | originaltimeline = [[Main timeline/television series|Main timeline]] | currenttimeline = [[Main timeline/television series|Main timeline]] | birthdate = | birthplace = | birthname = | deathdate = | deathplace = | deathcause = | residence =..."
wikitext
text/x-wiki
{{Character
| name = Frank Frink
| image =
| caption =
| fullname = Frank Frink
| aliases =
| title =
| originaltimeline = [[Main timeline/television series|Main timeline]]
| currenttimeline = [[Main timeline/television series|Main timeline]]
| birthdate =
| birthplace =
| birthname =
| deathdate =
| deathplace =
| deathcause =
| residence = [[San Francisco/television series/main timeline|San Francisco]], [[Japanese Pacific States/television series/main timeline|Japanese Pacific States]] <small>(formerly)</small>
| species = Human
| gender = Male
| pronouns =
| ethnicity = Jewish
| heightmetres =
| heightfeet =
| heightinches =
| weightkilograms =
| weightpounds =
| weightounces =
| haircolour = Black
| eyecolour = Blue
| parents =
| siblings = *[[Laura Crothers]] <small>(sister)</small>
*[[Bill Crothers]] <small>(brother-in-law)</small>
| spouse =
| children =
| relatives = *[[Emily Crothers]] <small>(niece)</small>
*[[John Crothers]] <small>(nephew)</small>
*[[Sheldon Frink]] <small>(paternal grandfather)</small>
| citizenship = [[Japanese Pacific States/television series/main timeline|Japanese Pacific States]]
| occupation = *Artist <small>(formerly)</small>
*Factory worker <small>(formerly)</small>
| employer =
| affiliation = [[American Resistance/television series/main timeline|American Resistance]]
}}
'''Frank Frink''' is a male member of the [[American Resistance/television series/main timeline|American Resistance]].
==Biography==
''To be added''
==Appearances==
===Season One===
*Episode 1: "[[The New World]]"
{{DEFAULTSORT:Frink, Frank}}
[[Category:American Resistance members]]
[[Category:Citizens if the Japanese Pacific States]]
[[Category:Frink family]]
[[Category:Males]]
17d67eb418da81ff4a822293ecc59ff1176ff925
67
66
2023-12-28T01:15:32Z
CreepersNeedHugs
2
wikitext
text/x-wiki
{{Character
| name = Frank Frink
| image =
| caption =
| fullname = Frank Frink
| aliases =
| title =
| originaltimeline = [[Main timeline/television series|Main timeline]]
| currenttimeline = [[Main timeline/television series|Main timeline]]
| birthdate =
| birthplace =
| birthname =
| deathdate =
| deathplace =
| deathcause =
| residence = [[San Francisco/television series/main timeline|San Francisco]], [[Japanese Pacific States/television series/main timeline|Japanese Pacific States]] <small>(formerly)</small>
| species = Human
| gender = Male
| pronouns =
| ethnicity = Jewish
| heightmetres =
| heightfeet =
| heightinches =
| weightkilograms =
| weightpounds =
| weightounces =
| haircolour = Black
| eyecolour = Blue
| parents =
| siblings = *[[Laura Crothers]] <small>(sister)</small>
*[[Bill Crothers]] <small>(brother-in-law)</small>
| spouse =
| children =
| relatives = *[[Emily Crothers]] <small>(niece)</small>
*[[John Crothers]] <small>(nephew)</small>
*[[Sheldon Frink]] <small>(paternal grandfather)</small>
| citizenship = [[Japanese Pacific States/television series/main timeline|Japanese Pacific States]]
| occupation = *Artist <small>(formerly)</small>
*Factory worker <small>(formerly)</small>
| employer =
| affiliation = [[American Resistance/television series/main timeline|American Resistance]]
}}
'''Frank Frink''' is a male member of the [[American Resistance/television series/main timeline|American Resistance]].
==Biography==
''To be added''
==Appearances==
===Season One===
*Episode 1: "[[The New World]]"
{{DEFAULTSORT:Frink, Frank}}
[[Category:American Resistance members]]
[[Category:Citizens of the Japanese Pacific States]]
[[Category:Frink family]]
[[Category:Males]]
0858706989277c4e761fda1ef3f42c5419b724ac